@graffiticode/l0175 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.
Files changed (41) hide show
  1. package/dist/compiler.d.ts +12 -0
  2. package/dist/compiler.d.ts.map +1 -0
  3. package/dist/compiler.js +1285 -0
  4. package/dist/compiler.js.map +1 -0
  5. package/dist/embedding.d.ts +64 -0
  6. package/dist/embedding.d.ts.map +1 -0
  7. package/dist/embedding.js +294 -0
  8. package/dist/embedding.js.map +1 -0
  9. package/dist/index.d.ts +7 -0
  10. package/dist/index.d.ts.map +1 -0
  11. package/dist/index.js +8 -0
  12. package/dist/index.js.map +1 -0
  13. package/dist/lexicon.d.ts +644 -0
  14. package/dist/lexicon.d.ts.map +1 -0
  15. package/dist/lexicon.js +101 -0
  16. package/dist/lexicon.js.map +1 -0
  17. package/dist/static/instructions.md +527 -0
  18. package/dist/static/language-info.json +85 -0
  19. package/dist/static/lexicon.json +1112 -0
  20. package/dist/static/schema.json +162 -0
  21. package/dist/static/scope.json +28 -0
  22. package/dist/static/spec.html +572 -0
  23. package/dist/static/stems.md +374 -0
  24. package/dist/static/template.gc +67 -0
  25. package/dist/static/usage-guide.md +111 -0
  26. package/package.json +33 -0
  27. package/spec/README.md +18 -0
  28. package/spec/data/examples.gc +84 -0
  29. package/spec/data/examples_with_explanations.md +124 -0
  30. package/spec/data/training_examples.json +122 -0
  31. package/spec/docs.md +102 -0
  32. package/spec/examples.md +91 -0
  33. package/spec/instructions.md +337 -0
  34. package/spec/language-info.json +78 -0
  35. package/spec/schema.json +162 -0
  36. package/spec/scope.json +28 -0
  37. package/spec/spec.md +277 -0
  38. package/spec/stems.md +374 -0
  39. package/spec/template.gc +67 -0
  40. package/spec/unparse-hints.json +3 -0
  41. package/spec/usage-guide.md +111 -0
@@ -0,0 +1,101 @@
1
+ // SPDX-License-Identifier: MIT
2
+ // L0175's lexicon = L0000's base vocabulary + L0175's ELA item-composition additions
3
+ // (child keys win on merge). The authoring surface is the l0169 "builder" idiom:
4
+ // - attribute functions are arity-2 (value, continuation) and merge one key into the
5
+ // continuation record: `attr value cont` -> { ...cont, key: value };
6
+ // - collection builders are arity-2 (list, continuation);
7
+ // - element wrappers are arity-1 (the assembled attribute-chain record).
8
+ // A program is one flat chain terminated by a single `{}` at the end.
9
+ //
10
+ // Enum VALUES (ebsr, character, misreads-detail, rl-1, ...) are bare kebab-case identifiers
11
+ // with NO lexicon entries: an undefined identifier resolves to its own lexeme string via
12
+ // L0000's IDENT fallback, and composition validates it against the allowed set.
13
+ import { lexicon as base } from "@graffiticode/l0000";
14
+ const fn2 = (name) => ({ tk: 1, name, cls: "function", length: 2, arity: 2 });
15
+ const fn1 = (name) => ({ tk: 1, name, cls: "function", length: 1, arity: 1 });
16
+ // Enum values are bare kebab-case identifiers registered as nullary tags (tk:22, name:"TAG").
17
+ // The parser rejects undefined references, so each must be a lexicon entry; at transform time
18
+ // a tag resolves to a `{ tag: <lexeme> }` value, which composition normalizes to its string.
19
+ // The flat UNION of valid bare tags across all targets. Each target profile (in compiler.ts)
20
+ // restricts which dimensions/standards are valid for that target; the lexicon only needs to
21
+ // register every tag so the parser accepts it.
22
+ const ENUM_VALUES = [
23
+ "literary", "informational",
24
+ "ebsr", "hot-text", "short-text",
25
+ // single-part item types (Multiple Choice / Multi-Select) — used by T9 and the later T8/T10
26
+ "multiple-choice", "multi-select",
27
+ // learning targets (the top-level `target` selector)
28
+ "c1-t4", "c1-t11", "c1-t9", "c1-t8", "c1-t10",
29
+ // T4 (literary) dimensions
30
+ "character", "setting", "event", "point-of-view",
31
+ "theme", "topic", "narrators-feelings", "character-relationship",
32
+ // T11 (informational) dimensions (point-of-view shared with T4)
33
+ "relationships-interactions", "author-use-of-information", "purpose", "authors-opinion",
34
+ // T9 (Central Ideas) dimensions
35
+ "central-idea", "key-detail", "summary",
36
+ // T8 (Key Details) dimension
37
+ "supporting-evidence",
38
+ // T10 (Word Meanings) dimension
39
+ "word-meaning",
40
+ "supported", "distractor", "correct",
41
+ "directly-supports", "supports-wrong-claim", "irrelevant",
42
+ // error taxonomies: Reasoning & Evidence (T4/T11) + Central Ideas (T9, significance-based)
43
+ "misreads-detail", "erroneous-inference", "faulty-reasoning",
44
+ "too-narrow", "too-broad", "insignificant",
45
+ // Word Meanings (T10) distractor taxonomy
46
+ "other-meaning", "misinterprets", "wrong-context",
47
+ // standards: RL (T4) + RI (T11/T9/T8/T10) + L (T10)
48
+ "rl-1", "rl-3", "rl-6", "rl-9",
49
+ "ri-1", "ri-2", "ri-3", "ri-4", "ri-6", "ri-7", "ri-8", "ri-9",
50
+ "l-4", "l-4a", "l-4b", "l-4c", "l-5c",
51
+ "r-dok1", "r-dok2", "r-dok3",
52
+ "inference", "conclusion", "author-intent",
53
+ ];
54
+ const enums = Object.fromEntries(ENUM_VALUES.map((v) => [v, { tk: 22, name: "TAG", cls: "val", length: 0, arity: 0 }]));
55
+ const additions = {
56
+ // --- attribute functions (arity-2) ---
57
+ id: fn2("ID"),
58
+ status: fn2("STATUS"),
59
+ dimension: fn2("DIMENSION"),
60
+ "error-type": fn2("ERROR_TYPE"),
61
+ text: fn2("TEXT"),
62
+ rationale: fn2("RATIONALE"),
63
+ cites: fn2("CITES"), // claim -> evidence id list
64
+ targets: fn2("TARGETS"), // distractor claim -> outcome id list (the questions it foils)
65
+ line: fn2("LINE"), // evidence -> passage line number
66
+ quote: fn2("QUOTE"), // optional evidence text override
67
+ supports: fn2("SUPPORTS"), // evidence -> claim id list
68
+ type: fn2("TYPE"), // passage type OR item type (contextual)
69
+ subject: fn2("SUBJECT"),
70
+ standard: fn2("STANDARD"),
71
+ focus: fn2("FOCUS"), // optional forced correct-claim id
72
+ passage: fn2("PASSAGE"), // passage heading
73
+ lines: fn2("LINES"), // passage line strings (auto-indexed)
74
+ title: fn2("TITLE"),
75
+ target: fn2("TARGET"), // top-level SBAC learning target selector (c1-t4 | c1-t11)
76
+ grade: fn2("GRADE"), // optional top-level grade override; defaults to the target's grade
77
+ stem: fn2("STEM"),
78
+ rubric: fn2("RUBRIC"),
79
+ dok: fn2("DOK"),
80
+ plausibility: fn2("PLAUSIBILITY"), // optional 0..1 author override for distractor ranking
81
+ mode: fn2("MODE"), // stem mode: inference | conclusion | author-intent
82
+ other: fn2("OTHER"), // second subject, for character-relationship stems
83
+ "stem-b": fn2("STEM_B"), // optional Part B stem override
84
+ score: fn2("SCORE"), // rubric band score
85
+ descriptor: fn2("DESCRIPTOR"), // rubric band descriptor
86
+ // --- collection builders (arity-2) ---
87
+ claims: fn2("CLAIMS"),
88
+ evidence: fn2("EVIDENCE"),
89
+ outcomes: fn2("OUTCOMES"),
90
+ words: fn2("WORDS"), // T10 (Word Meanings) — targeted words, top level
91
+ meanings: fn2("MEANINGS"), // candidate meanings inside a `word`
92
+ // --- element wrappers (arity-1) ---
93
+ claim: fn1("CLAIM"),
94
+ source: fn1("SOURCE"),
95
+ outcome: fn1("OUTCOME"),
96
+ band: fn1("BAND"), // a rubric band: score + descriptor
97
+ word: fn1("WORD"), // T10 — a targeted word + its candidate meanings
98
+ meaning: fn1("MEANING"), // T10 — one candidate meaning (correct or distractor)
99
+ };
100
+ export const lexicon = { ...base, ...enums, ...additions };
101
+ //# sourceMappingURL=lexicon.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lexicon.js","sourceRoot":"","sources":["../src/lexicon.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,527 @@
1
+ <!-- SPDX-License-Identifier: CC-BY-4.0 -->
2
+ **Note:** This document trains the dialect-specific code-generation model. It is not a guide for client AI agents. Client agents must not write Graffiticode directly — describe the intended behavior in natural language and let the Graffiticode backend generate the code.
3
+
4
+ # Core Graffiticode Instructions
5
+
6
+ This is the core Graffiticode language — a functional language with prefix notation, first-class lambdas, pattern matching, and immutable data.
7
+
8
+ ## Response Requirements
9
+
10
+ - **IMPORTANT**: Whatever the user request is, the response should always be a complete Graffiticode program terminated with `..`.
11
+ - Programs consist of zero or more `let` declarations followed by a single top-level expression, all terminated with `..`.
12
+
13
+ ## Program Structure
14
+
15
+ ```
16
+ let name = value..
17
+ expression..
18
+ ```
19
+
20
+ ### Minimal example
21
+
22
+ ```
23
+ add 1 2..
24
+ ```
25
+
26
+ ### With let bindings
27
+
28
+ ```
29
+ let double = <x: mul 2 x>..
30
+ map (double) [1 2 3]..
31
+ ```
32
+
33
+ ## Syntax Rules
34
+
35
+ - **Prefix notation**: Functions are applied by writing the function name followed by its arguments: `add 1 2`
36
+ - **Fixed arity**: Every function has a known number of parameters, so applications parse unambiguously without grouping: `add 1 mul 2 3` parses as `add(1, mul(2, 3))`
37
+ - **Parentheses defer application**: `map (double) [1 2 3]` passes `double` as a value rather than applying it
38
+ - **Program terminator**: Every program ends with `..`
39
+ - **Let terminator**: Every `let` binding ends with `..`
40
+ - **Comments**: Block comments are enclosed in `/* ... */`
41
+
42
+ ## Data Types
43
+
44
+ - **Numbers**: `42`, `3.14`, `-1`
45
+ - **Strings**: `"hello"`
46
+ - **Booleans**: `true`, `false`
47
+ - **Lists**: `[1 2 3]`
48
+ - **Records**: `{name: "Alice", age: 30}`
49
+ - **Tags**: `tag red`, `tag foo`
50
+ - **Lambdas**: `<x: add x 1>`, `<x y: add x y>`
51
+
52
+ ## Tags
53
+
54
+ Tag values are symbolic constants created with the `tag` keyword:
55
+
56
+ ```
57
+ let red = tag red..
58
+ let blue = tag blue..
59
+ ```
60
+
61
+ Tags have value semantics — same name means same tag. Tags can be matched in `case` expressions:
62
+
63
+ ```
64
+ let color = tag red..
65
+ case color of
66
+ red: "warm"
67
+ blue: "cool"
68
+ _: "other"
69
+ end..
70
+ ```
71
+
72
+ ## Pattern Matching
73
+
74
+ ```
75
+ case x of
76
+ 0: "zero"
77
+ 1: "one"
78
+ _: "other"
79
+ end
80
+ ```
81
+
82
+ Supports:
83
+ - Literal values
84
+ - Tag values (matched by identity)
85
+ - Tuple destructuring: `(a, b)`
86
+ - Record destructuring: `{ name, age }`
87
+ - Wildcard `_`
88
+
89
+ ## Record Shorthand
90
+
91
+ Fields where the value is a variable of the same name can use shorthand:
92
+
93
+ ```
94
+ let x = 1..
95
+ let y = 2..
96
+ {x y z: 3}..
97
+ ```
98
+
99
+ This is equivalent to `{x: 1, y: 2, z: 3}`.
100
+
101
+ ## Available Functions
102
+
103
+ | Function | Signature | Description |
104
+ | :------- | :-------- | :---------- |
105
+ | `add` | `<number number: number>` | Adds two numbers |
106
+ | `and` | `<bool bool: bool>` | Logical AND |
107
+ | `append` | `<any list: list>` | Appends an element to the end of a list |
108
+ | `apply` | `<function list: any>` | Applies a function to a list of arguments |
109
+ | `concat` | `<string\|list string\|list: string\|list>` | Concatenates two strings or two lists |
110
+ | `cons` | `<any list: list>` | Prepends an element to a list |
111
+ | `data` | `<record: record>` | Returns upstream task data, or the argument if none. Argument may be a record literal (e.g. `data {x: 1}`) or `use "<lang>"` to declare the upstream language |
112
+ | `div` | `<number number: number>` | Divides numbers |
113
+ | `drop` | `<integer list: list>` | Returns a list with the first n elements removed |
114
+ | `eq` | `<number number: bool>` | Numeric equality |
115
+ | `equiv` | `<any any: bool>` | Semantic equivalence for any type, including tags |
116
+ | `filter` | `<function list: list>` | Keeps items matching predicate |
117
+ | `ge` | `<number number: bool>` | Greater than or equal |
118
+ | `get` | `<string record: any>` | Retrieves a value from a record by key |
119
+ | `get-val-private` | `<string: string>` | Resolves a named variable, encrypted at parse time and decrypted at compile time |
120
+ | `get-val-public` | `<string: string>` | Resolves a named variable as plain text |
121
+ | `get-var` | `<string: any>` | Gets the value of a named variable |
122
+ | `gt` | `<number number: bool>` | Greater than |
123
+ | `hd` | `<list: any>` | First item of list |
124
+ | `isempty` | `<list: bool>` | Returns true if the list is empty |
125
+ | `json` | `<string: any>` | Parses a string as JSON |
126
+ | `last` | `<list: any>` | Returns the last element of a list |
127
+ | `le` | `<number number: bool>` | Less than or equal |
128
+ | `length` | `<list\|string: integer>` | Returns the length of a list or string |
129
+ | `log` | `<any: any>` | Logs to console and returns the value |
130
+ | `lt` | `<number number: bool>` | Less than |
131
+ | `map` | `<function list: list>` | Applies function to each item |
132
+ | `max` | `<number number: number>` | Returns the larger of two numbers |
133
+ | `min` | `<number number: number>` | Returns the smaller of two numbers |
134
+ | `mod` | `<number number: number>` | Remainder of division |
135
+ | `mul` | `<number number: number>` | Multiplies numbers |
136
+ | `ne` | `<number number: bool>` | Not equal |
137
+ | `not` | `<bool: bool>` | Logical NOT |
138
+ | `nth` | `<number list: any>` | Nth element of list (0-based) |
139
+ | `or` | `<bool bool: bool>` | Logical OR |
140
+ | `pow` | `<number number: number>` | Raises first number to the power of second |
141
+ | `print` | `<any: record>` | Outputs a value to the form |
142
+ | `range` | `<number number number: list>` | Generates a range list (start, end, step) |
143
+ | `reduce` | `<function any list: any>` | Combines list using a reducer with initial value |
144
+ | `set` | `<string any record: record>` | Returns a new record with a key set to a value |
145
+ | `set-var` | `<string any: any>` | Sets a named variable to a value |
146
+ | `sub` | `<number number: number>` | Subtracts numbers |
147
+ | `take` | `<integer list: list>` | Returns the first n elements of a list |
148
+ | `tl` | `<list: list>` | All items except first |
149
+ | `use` | `<string: record>` | Inside `data`, declares the upstream language whose output is expected (e.g. `data use "0166"`). Evaluates to `{}` when no upstream is bound |
150
+
151
+ ## Examples
152
+
153
+ ### Arithmetic
154
+ ```
155
+ add 1 mul 2 3..
156
+ ```
157
+
158
+ ### List operations
159
+ ```
160
+ let nums = [1 2 3 4 5]..
161
+ let evens = filter (<x: eq 0 mod x 2>) nums..
162
+ reduce (<a b: add a b>) 0 evens..
163
+ ```
164
+
165
+ ### Record manipulation
166
+ ```
167
+ let person = {name: "Alice", age: 30}..
168
+ set "age" 31 person..
169
+ ```
170
+
171
+ ### Pattern matching with tags
172
+ ```
173
+ let red = tag red..
174
+ let blue = tag blue..
175
+ let color = red..
176
+ case color of
177
+ red: "warm"
178
+ blue: "cool"
179
+ _: "unknown"
180
+ end..
181
+ ```
182
+
183
+ ### Higher-order functions
184
+ ```
185
+ let double = <x: mul 2 x>..
186
+ let inc = <x: add x 1>..
187
+ map (double) map (inc) [1 2 3]..
188
+ ```
189
+
190
+
191
+ <!-- SPDX-License-Identifier: CC-BY-4.0 -->
192
+ <!-- gc:model=opus -->
193
+ # L0175 Dialect Extensions
194
+
195
+ _Revised: 2026-06-19_
196
+
197
+ L0175 composes 5th-grade ELA assessment items (Smarter Balanced · Grade 5 · Claim 1 ·
198
+ Reasoning & Evidence) from an authored, inline superset of tagged content. One language serves
199
+ **multiple learning targets**; a program selects its target up front.
200
+
201
+ ## Step 0 — pick the learning target
202
+
203
+ Always declare a top-level `target` (the SBAC learning target the program composes for):
204
+
205
+ - **`c1-t4`** — Target 4: Reasoning & Evidence over **literary** texts (RL standards). Dimensions:
206
+ `character`, `setting`, `event`, `point-of-view`, `theme`, `topic`, `narrators-feelings`,
207
+ `character-relationship`. Standards: `rl-1` (always) + `rl-3` / `rl-6` / `rl-9`.
208
+ - **`c1-t11`** — Target 11: Reasoning & Evidence over **informational** texts (RI standards).
209
+ Dimensions: `relationships-interactions`, `author-use-of-information`, `point-of-view`,
210
+ `purpose`, `authors-opinion`. Standards: `ri-1` (always) + `ri-3` / `ri-6` / `ri-7` / `ri-8` / `ri-9`.
211
+ - **`c1-t9`** — Target 9: **Central Ideas** over **informational** texts (RI standards). A
212
+ DIFFERENT skill from Reasoning & Evidence — synthesize and condense: the main/central idea, the
213
+ key details that build it, and summary (NOT inference + justification). Dimensions: `central-idea`,
214
+ `key-detail`, `summary`. Standards: `ri-1` (always) + `ri-2`. **DOK 2** (3 only for the written
215
+ summary). Item types: `multiple-choice`, `multi-select`, `ebsr`, `short-text`, and single-part
216
+ `hot-text` (click the sentence(s) that show the main idea — its directly-supporting `source`s are
217
+ the correct selection). Distractors use a **significance** taxonomy (`too-narrow`,
218
+ `too-broad`, `misreads-detail`, `insignificant`) — usually true statements that just aren't the
219
+ central idea.
220
+ - **`c1-t8`** — Target 8: **Key Details** over **informational** texts (RI standards). A DIFFERENT
221
+ model: the inference/conclusion is **GIVEN in the stem**, and the student selects the supporting
222
+ **evidence** (the answer is evidence, not a chosen statement). Dimension: `supporting-evidence`.
223
+ Standards: `ri-1` (always) + `ri-7`. **DOK 1–2**. Item types: `multiple-choice`, `multi-select`,
224
+ `hot-text` (single-part) — no EBSR, no short-text. **Author ONE supported `claim` = the given
225
+ inference (its `focus`), state it in the `stem`, and author `source`s as the options:
226
+ `directly-supports` = correct evidence (with a `quote`), `supports-wrong-claim`/`irrelevant` =
227
+ distractor evidence. No distractor claims.**
228
+ - **`c1-t10`** — Target 10: **Word Meanings** over **informational** texts. The MOST different
229
+ model: the question asks for the **meaning of a targeted word/phrase in context**, so the answer
230
+ choices are **meanings**, authored as `word`/`meaning` (not claims). Dimension: `word-meaning`.
231
+ Standards: `ri-4` (always) + the L-4 family by strategy (`l-4a` context, `l-4b` roots/affixes,
232
+ `l-5c` word relationships, `l-4c` reference). **DOK 1–2**. Item types: `multiple-choice`,
233
+ `multi-select`, and `hot-text` (click the word in the excerpt matching a given definition).
234
+ **Author a top-level `words` list: a
235
+ `word` (the targeted word, with `line`/`quote` for context) holding `meanings` — one (MC) or ≥2
236
+ (Multi-Select) `status correct` + `status distractor` meanings (each with a T10 `error-type`
237
+ + `rationale`). The outcome's `focus` names the word; state the word + its context in the `stem`.**
238
+
239
+ **Infer the target — the user need not state it.** Decide from the passage and the skill asked: a
240
+ **literary** text (story/poem/narrative) → `c1-t4`; an **informational** text → an RI target. Among
241
+ informational targets, choose by skill: **reasoning** — infer/conclude and justify with evidence
242
+ (relationships between ideas, author's use of evidence, point of view/purpose/opinion) → `c1-t11`;
243
+ **central ideas** — the main idea, the key details that support it, or a summary → `c1-t9`;
244
+ **key details** — the request **states an inference/conclusion and asks which detail/sentence
245
+ supports it** (the answer is evidence) → `c1-t8`; **word meanings** — the request asks **what a
246
+ word/phrase means in context** → `c1-t10`. The skill also signals T4: character / theme /
247
+ narrator's point of view. When the text type is genuinely ambiguous, prefer `c1-t4`; for an
248
+ informational request, match the verbs: "infer/conclude/why" → T11; "main idea/summarize/most
249
+ about" → T9; "which detail/sentence supports [this stated idea]" → T8; "what does [word] mean" → T10.
250
+ Write the choice as the first top-level form: `target c1-t11`. Use the dimensions, standards, and
251
+ stem catalog (in `stems.md`) for that target; mixing targets' vocabularies is a compile error,
252
+ and the passage `type` should match the target (literary for T4; informational for T11 and T9). If
253
+ `target` is omitted entirely the compiler defaults to `c1-t4` and warns — so always emit one
254
+ explicitly rather than relying on the default.
255
+
256
+ ## Authoring contract
257
+
258
+ **Compose questions first (item-first).** After picking the target, author the N `outcome`s you
259
+ want — each with a unique `id`, a `focus` naming its correct claim, and an explicit `stem` (and
260
+ `stem-b` on EBSR) taken from the target's section of the Appropriate-Stem catalog (`stems.md`).
261
+ THEN author the supported claims each `focus` names, and a superset of distractor claims, each
262
+ tagged with `targets` listing the question id(s) it foils. The compiler draws an item's foils
263
+ ONLY from the distractors that target that outcome — so every wrong answer is authored against
264
+ that exact stem and key.
265
+
266
+ A program is ONE flat builder chain ending in a single `{}..`. Top-level forms
267
+ (`target`, `passage`, `type`, `lines`, `claims`, `evidence`, `outcomes`) chain with no `{}`
268
+ between them. Inside the `claims` / `evidence` / `outcomes` lists, each element (`claim` /
269
+ `source` / `outcome`) is its own attribute chain terminated by its own `{}`; whitespace separates
270
+ elements (commas are optional).
271
+
272
+ Quote free text (`text`, `rationale`, `subject`, passage heading) and id labels (`id`,
273
+ `cites`, `supports`). Write closed-enum values as bare kebab-case identifiers (`c1-t4`, `ebsr`,
274
+ `character`, `misreads-detail`, `directly-supports`, `rl-1`, `r-dok3`).
275
+
276
+ ## Forms and attributes
277
+
278
+ - **target** `c1-t4` | `c1-t11` — top level; selects the learning-target profile (dimensions,
279
+ standards, stem catalog). Always author one; if omitted, the compiler defaults to `c1-t4`.
280
+ - **grade** `<n>` — optional, top level (e.g. `grade 5`). The reading-level target the compiler
281
+ checks the passage against. Defaults to the guideline/target's grade (5 for `c1-t4`/`c1-t11`);
282
+ author one only to override when the user's prompt asks for a different grade.
283
+ - **passage** `"heading"` — plus `type` (`literary` | `informational`) and
284
+ `lines [ "..." ... ]`. **By default each entry is one PARAGRAPH of the passage**, auto-numbered
285
+ from 1 (so the passage shows numbered paragraphs, matching SBAC). **Preserve the paragraph breaks
286
+ the request supplies** — emit one `lines` entry per source paragraph; do not merge the passage
287
+ into a single entry or re-chunk it. Split by paragraph for **every** task model, including Hot
288
+ Text: the compiler segments each paragraph into sentences and makes each sentence individually
289
+ selectable in Hot Text Part B, so the passage keeps its paragraph layout — do **not** author the
290
+ passage as one sentence per line.
291
+ - **claim** — `id`, `status` (`supported` | `distractor`), `dimension` (required on supported
292
+ claims), `text`. A `distractor` also requires `error-type`, a non-empty `rationale`, and
293
+ `targets` (the outcome id(s) of the question(s) it foils). Optional: `cites` (evidence ids),
294
+ `subject`, `standard`, `dok`, and `plausibility` (a 0–1 override for how tempting a distractor
295
+ is — otherwise the compiler computes it from evidence overlap, structure, and error type when
296
+ choosing among the foils of the same error type that target the outcome).
297
+ - **source** — `id`, `line` (the numbered passage entry — a paragraph by default) or `quote`,
298
+ `status` (`directly-supports` | `supports-wrong-claim` | `irrelevant`), `supports` (claim ids).
299
+ Optional `rationale` explaining a foil. **For EBSR Part B, give the source a `quote` with the
300
+ exact supporting SENTENCE** while `line` points at the paragraph that contains it — so Part B
301
+ options stay tight sentences even though the passage is numbered by paragraph. (Without `quote`,
302
+ the option text is the whole paragraph at `line`.)
303
+ - **outcome** — `id` (required, unique — distractors target it), `type`
304
+ (`ebsr` | `hot-text` | `short-text` | `multiple-choice` | `multi-select`), `dimension`, `focus`
305
+ (required — the id of the supported correct claim; on `multi-select` a **list** of ids = the
306
+ correct set), `stem` (required — the Part A / single-question stem / short-text prompt, authored
307
+ from `stems.md`), and on EBSR `stem-b` (required — the Part B stem). Optional: `subject`,
308
+ `standard`, `dok`, and `rubric` (short-text only — a list of `band score <n> descriptor "…"`
309
+ elements; defaults to a 0/1/2 rubric if omitted).
310
+ - **band** — a rubric row: `band score 2 descriptor "…" {}`. Used only inside an outcome's `rubric`.
311
+ - **word** / **meaning** (**target `c1-t10` only**) — a top-level `words` list of `word`s; each
312
+ `word` has `id`, `text` (the targeted word/phrase), optional `line`/`quote` (its context), and a
313
+ `meanings` list. A `meaning` has `id`, `text` (the definition/synonym), `status`
314
+ (`correct` | `distractor`), and on a distractor an `error-type` (`other-meaning` | `misinterprets`
315
+ | `wrong-context`) + `rationale`. The outcome's `focus` names the `word`; its correct meaning(s)
316
+ are the key, the distractor meanings the foils. Example:
317
+ `words [ word id "w1" text "aqueduct" line 1 quote "The aqueduct carried water." meanings [ meaning id "m1" status correct text "a water channel" {} meaning id "m2" status distractor error-type other-meaning text "a boat" rationale "another meaning, ignores context" {} ] {} ]`
318
+ For a **click-the-word** (`hot-text`) item, author the focus `word` (the correct one) as the
319
+ outcome's `focus` with the `line` of its paragraph, then the **distractor candidate words** either
320
+ (a) as more single-word `word`s in the list, or (b) as the focus word's distractor `meanings`
321
+ whose `text` IS the candidate word (a single word, with error-type + rationale) — for hot-text the
322
+ meaning text must be the literal word to click, not a definition. **All candidates must be words
323
+ that appear in that one paragraph.** The compiler shows the paragraph and makes the candidate words
324
+ clickable, with the focus word correct. The `stem` is just the instruction + definition — do
325
+ **not** paste the paragraph into it (the compiler warns if you do). ⚠ If you author *only* the
326
+ focus word with a real multi-word definition (no candidate words), the compiler falls back to
327
+ making **every** content word clickable — list the candidate words to avoid that. Candidates not
328
+ in the focus word's paragraph are warned and dropped.
329
+ - A top-level **`title`** attribute (before `passage`) names the assessment; it is echoed on the output.
330
+
331
+ ## Stems (Appropriate Stems, SBAC G5 · C1 · T4)
332
+
333
+ **You author the stem; the compiler does not generate it. Use the guideline's Appropriate-Stem
334
+ templates verbatim — do not invent phrasings.** For each item, open the catalog in **`stems.md`**,
335
+ pick the one template that matches the item type (EBSR → Task Model 1, Hot Text → Task Model 2,
336
+ Short Text → Task Model 3) and the task (inference vs. conclusion vs. author-intent; plain
337
+ subject vs. narrator's-feelings vs. relationship), and fill its bracketed `[...]` slot. Author
338
+ `stem` (Part A / short-text prompt) and, on EBSR, `stem-b` (Part B). Common Part A choices:
339
+
340
+ - inference — "Which of these inferences about [...] is supported by the passage?"
341
+ - conclusion — "Which of these conclusions about [...] is supported by the passage?"
342
+ - author-intent — "What did the author most likely mean by including [...] in the passage?"
343
+
344
+ **Specificity rule (required).** Fill the `[...]` slot — the guideline's
345
+ `[provide character's name / setting / event / author's point of view / theme / topic]` slot —
346
+ with the **specific** reference the question is about, the same string you put in `subject`:
347
+ `character`→ the character's name (`"Mother"`); `point-of-view`→ `"the narrator's point of view"`;
348
+ `setting` / `event` / `theme` / `topic`→ the specific setting/event/theme/topic;
349
+ `narrators-feelings`→ "the narrator's feelings toward {subject}"; `character-relationship`→
350
+ "{subject}'s relationship with {other}". Do **not** leave it generic (`"the character"`) and do
351
+ **not** pad it — write `"the theme"`, not `"the theme of the passage"` (the stem already ends
352
+ "…supported by the passage"). A specific subject is what makes the four answer choices
353
+ discriminating. Hot Text uses the "Click on the statement…" forms; Short Text ends with
354
+ "Explain using key details from the passage to support your answer."
355
+
356
+ **Hot Text Part A asks for the best STATEMENT — never for passage sentences.** The Part A `stem`
357
+ must be a Task Model 2 "Click on the statement that best provides an inference/conclusion about
358
+ [...]" prompt whose four options are inference `claim`s. Selecting the supporting sentences is
359
+ **Part B**, which the compiler fixes automatically — you never author it. **Translate a request
360
+ that says "select/click the sentences that show [X]"**: that phrasing describes the *Part B*
361
+ target, not the Part A stem. Author Part A as "Click on the statement that best provides an
362
+ inference about [X] that is supported by the passage." (a statement about [X]), make the correct
363
+ `claim` that inference, and mark the sentences that show [X] as `directly-supports` evidence with
364
+ exact `quote`s — those become Part B's correct selections. Do **not** copy "select the sentences
365
+ that…" into the `stem`. The compiler warns ("Hot Text Part A must ask for the best STATEMENT…")
366
+ when a Hot Text Part A stem mentions sentences.
367
+
368
+ The concrete answer and its foils are authored as `claim`s (the correct claim, named by the
369
+ outcome's `focus`, states the inferred fact, e.g. "Cortez is about twelve"; its foils `targets`
370
+ the outcome). Remember the answer must be **inferable from evidence** (Target 4) — a fact stated
371
+ outright is literal recall and out of scope.
372
+
373
+ ## Authoring guidance
374
+
375
+ - For each EBSR/Hot-Text outcome, author **at least 5 viable distractor claims that `targets`
376
+ it**, covering all three error types (`misreads-detail`, `erroneous-inference`,
377
+ `faulty-reasoning`) — with ≥2 alternatives in at least two of the types. An item draws only 3
378
+ foils, so a deeper targeted pool gives selection real choice. **Fewer than 3 targeted foils is
379
+ a hard error** (the item can't be composed); fewer than 5 triggers a composition warning.
380
+ - A distractor may `targets` more than one question when it genuinely foils each (e.g. several
381
+ items built around the same correct claim). Keep foils written to the specific stem + key they
382
+ target — that is the whole point of binding by `targets` rather than by dimension.
383
+ - **Over-generate: aim for 5–8 distinct distractors per question** (some will be filtered as
384
+ near-duplicates or accidentally correct), spanning a spread of difficulty, and give each a
385
+ `plausibility` score (0–1) for how tempting it is to a partial-understander. Composition selects
386
+ the most plausible foil per error type from this scored pool; if a score is omitted the compiler
387
+ computes one from the inference graph (evidence overlap, structure, error type).
388
+ - Tag evidence so Part B has material: mark the sources that **directly support** the correct
389
+ claim, and author **at least 5 non-supporting foil sources** — `supports-wrong-claim` sources
390
+ plus `irrelevant` sources. EBSR Part B draws 3 foils + the correct source; a pool of ≥5 lets the
391
+ compiler pick the most tempting 3. Fewer than 5 triggers a composition warning. Give each EBSR
392
+ Part B source a `quote` with the exact supporting **sentence** (and a `line` pointing at its
393
+ paragraph), so the four Part B options are tight sentences rather than whole paragraphs.
394
+ - **Hot Text Part B selects sentences, not paragraphs.** Keep the passage split by paragraph; the
395
+ compiler segments each paragraph into sentences and exposes every sentence as a selectable Part B
396
+ option, preserving the paragraph layout. Mark the correct sentence(s) by giving each
397
+ `directly-supports` source a `quote` with the exact supporting **sentence** (and a `line` at its
398
+ paragraph). A `directly-supports` source with no `quote` marks every sentence of its `line`
399
+ correct.
400
+ - **Hot Text Part B asks for an EXACT number of sentences from a SUPERSET of valid answers.** The
401
+ valid (directly-supporting) sentences are a superset; the student must select a specific count,
402
+ and **any selection of that many drawn from the valid set is correct** — they never have to find
403
+ every one. The compiler sets the count to **one less than the valid count** (a proper subset),
404
+ floored at 1 (one valid sentence) and capped at 3 (so it stays ≤3 once there are more than 4
405
+ valid): `count = min(3, validCount − 1)`, or 1 when `validCount ≤ 1`. It writes the matching
406
+ "Click N sentence(s)…" instruction. **Author a real superset: mark every sentence that genuinely
407
+ supports the inference as a `directly-supports` source with an exact `quote` — aim for ≥3 so the
408
+ asked count is ≥2 and there's real choice.** With only one valid sentence the compiler warns and
409
+ the answer is that single sentence.
410
+ - **No-giveaway rule (EBSR Part B): for every EBSR question, author at least one
411
+ `supports-wrong-claim` line whose `supports` lists BOTH the correct claim's id AND a
412
+ distractor's id** — a passage line that *seems* to back the correct inference but actually
413
+ props up a misreading. Part B asks "which line supports your Part A answer?"; if none of the
414
+ Part B foils also point at the correct claim, the correct line is the only one "about" the
415
+ right answer, so a student can back into Part A from the evidence (and the compiler warns
416
+ "possible A↔B giveaway"). Tie the shared line to a distractor you expect Part A to use, so it
417
+ is selected as a Part B foil. Do **not** make every `supports-wrong-claim` line point only at
418
+ distractors — that is exactly what triggers the warning.
419
+ Example: `source id "e2" line 2 status supports-wrong-claim supports ["c1" "c2"] {}` — `c1` is
420
+ the correct claim, `c2` one of its foils; this line tempts in both Part A and Part B.
421
+ - **Length-balance rule (no length giveaway): keep the correct claim's `text` parallel in
422
+ length and detail to its distractors.** A frequent tell is the key being the longest, most
423
+ qualified, most-detailed option — a partial-understander learns to pick "the long one." Write
424
+ the correct claim as tersely as it can be stated, and give the foils comparable specificity
425
+ (similar clause count and roughly the same length) rather than short, flat statements. The same
426
+ applies to the EBSR Part B `quote`s — pick supporting and non-supporting sentences of similar
427
+ length. The compiler flags a "possible length giveaway" warning when the correct option is the
428
+ longest AND notably longer than the average distractor; treat that warning as a cue to pad the
429
+ foils or trim the key.
430
+ - **Stem-wording rule (no answer echo): the Part A stem must not reuse the correct option's
431
+ wording.** Keep the stem a neutral question that names only the subject/skill (fill the catalog
432
+ template's `[...]` slot with the subject, e.g. "the narrator's point of view" or "how the city's
433
+ systems helped people") — do **not** restate the correct claim's phrasing in the stem. If the
434
+ stem already contains the answer's distinctive words ("...that best show that the city *had
435
+ systems that helped people move around the city and get fresh water*", when the key says the
436
+ city "*had built systems … that let people move through the city and get fresh water*"), the
437
+ answer is obvious without reading the options. **Paraphrase** so the stem and the key share only
438
+ the subject, and word the correct option in the passage's own terms. This applies to **every
439
+ Hot Text and EBSR question, across all targets**. The compiler warns ("Part A: the stem reuses
440
+ much of the correct option's wording …") when the stem reuses most of the key's content words —
441
+ treat it as a cue to reword the stem.
442
+ - **Grade-appropriate text complexity: author the passage AND all question text at the target
443
+ grade.** The grade is the guideline/target's grade (Grade 5 for `c1-t4`/`c1-t11`) unless the
444
+ user asks for another, in which case set a top-level `grade <n>`. At the Grade-5 instance:
445
+ reading level near the CCSS grade-4–5 band (Lexile ≈ 740–1010L, Flesch–Kincaid grade ≈ 4.5–6.0);
446
+ sentences mostly simple/compound, averaging ~12–16 words; concrete, high-frequency vocabulary
447
+ with at most a few context-clear Tier-2 words (avoid abstract/academic Tier-3 diction); a single
448
+ passage ≈ 150–350 words; figurative language sparing and accessible. **The reasoning must be
449
+ grade-level too:** DOK 3 means strategic thinking *within* grade-level text, so the correct
450
+ inference comes from concrete textual details — what a character does or says, a stated cause and
451
+ effect — not college-style thematic or authorial-technique analysis. Keep distractor, option, and
452
+ rationale text in the same register as the passage; a wrong answer that reads more academic than
453
+ the text gives itself away. The compiler estimates the passage's reading level and warns when it
454
+ runs above the target grade — treat that warning as a cue to shorten sentences and simplify
455
+ vocabulary. Scale the figures with the grade for non-Grade-5 targets.
456
+ - Distractor rationales must state *why a student would plausibly choose the foil* (the error
457
+ it targets). They appear in the item's `distractorAnalysis` output.
458
+ - The same passage + superset can drive several outcomes; add one `outcome` per item you want.
459
+
460
+ ## Built-in enumerations
461
+
462
+ - `target`: `c1-t4`, `c1-t11`, `c1-t9`, `c1-t8`, `c1-t10` (top level; always author one — defaults to `c1-t4` if omitted)
463
+ - `grade`: a number (top level, optional; defaults to the target's grade — 5 for all current targets)
464
+ - item `type`: `ebsr`, `hot-text`, `short-text`, `multiple-choice`, `multi-select` · passage `type`: `literary`, `informational`
465
+ (allowed per target — T4/T11: ebsr/hot-text/short-text · T9: multiple-choice/multi-select/ebsr/hot-text/short-text · T8: multiple-choice/multi-select/hot-text · T10: multiple-choice/multi-select/hot-text)
466
+ - `dimension` (**c1-t4**): `character`, `setting`, `event`, `point-of-view`, `theme`, `topic`, `narrators-feelings`, `character-relationship`
467
+ - `dimension` (**c1-t11**): `relationships-interactions`, `author-use-of-information`, `point-of-view`, `purpose`, `authors-opinion`
468
+ - `dimension` (**c1-t9**): `central-idea`, `key-detail`, `summary` · (**c1-t8**): `supporting-evidence` · (**c1-t10**): `word-meaning`
469
+ - claim `status`: `supported`, `distractor` · source `status`: `directly-supports`, `supports-wrong-claim`, `irrelevant` · meaning `status` (c1-t10): `correct`, `distractor`
470
+ - `error-type` (**c1-t4 / c1-t11**): `misreads-detail`, `erroneous-inference`, `faulty-reasoning` · (**c1-t9**): `too-narrow`, `too-broad`, `misreads-detail`, `insignificant` · (**c1-t8**): none — wrong answers are non-supporting `source`s · (**c1-t10**): `other-meaning`, `misinterprets`, `wrong-context`
471
+ - `standard` (**c1-t4**): `rl-1`, `rl-3`, `rl-6`, `rl-9` · (**c1-t11**): `ri-1`, `ri-3`, `ri-6`, `ri-7`, `ri-8`, `ri-9` · (**c1-t9**): `ri-1`, `ri-2` · (**c1-t8**): `ri-1`, `ri-7` · (**c1-t10**): `ri-4`, `l-4`, `l-4a`, `l-4b`, `l-4c`, `l-5c`
472
+ - `dok`: `r-dok1`, `r-dok2`, `r-dok3` (R&E items are `r-dok3`; T9 selected-response is `r-dok2`, its written summary `r-dok3`; T8 & T10 are `r-dok2`)
473
+
474
+ ## What composition does
475
+
476
+ For each outcome the compiler takes the correct claim named by `focus`, draws that outcome's
477
+ foils from the distractors that `targets` it (selecting for error-type coverage and
478
+ plausibility), uses the authored `stem`/`stem-b`, builds the task-model item, and emits
479
+ `distractorAnalysis` (every foil's error type + rationale + the claim it ties to), an
480
+ `answerKey`, the matched `standards` and `dok`, and `warnings` when the targeted pool is thin.
481
+ It never generates content or stems — author them.
482
+
483
+ ## Example (Target 4, literary)
484
+
485
+ ```
486
+ target c1-t4
487
+ passage "The Tide Pool"
488
+ type literary
489
+ /* lines are PARAGRAPHS, auto-numbered 1..N; EBSR Part B sources `quote` the exact sentence */
490
+ lines [
491
+ "Mara crouched at the edge of the tide pool, ignoring the picnic behind her. Her brother called twice, but she did not turn around. A tiny crab scuttled under a rock, and Mara smiled for the first time all day."
492
+ "She traced the cold water as if the pool were the only thing that mattered. Behind her, paper plates rustled and her mother laughed."
493
+ ]
494
+ claims [
495
+ claim id "c1" status supported dimension character subject "Mara"
496
+ text "Mara is more interested in the tide pool than in her family's picnic."
497
+ cites ["e1" "e3"] {}
498
+ /* at least 5 viable distractors targeting q1; the item draws 3 (one per error type) */
499
+ claim id "c2" status distractor error-type misreads-detail plausibility 0.85 targets ["q1"]
500
+ text "Mara is angry at her brother."
501
+ rationale "Not turning around shows absorption, not anger." cites ["e2"] {}
502
+ claim id "c3" status distractor error-type misreads-detail plausibility 0.6 targets ["q1"]
503
+ text "Mara is bored and wants to leave."
504
+ rationale "Her stillness is focus, not boredom (the crab makes her smile)." cites ["e2"] {}
505
+ claim id "c4" status distractor error-type erroneous-inference plausibility 0.55 targets ["q1"]
506
+ text "Mara dislikes being outdoors."
507
+ rationale "Over-generalizes from her quiet to a dislike the text contradicts." cites ["e3"] {}
508
+ claim id "c5" status distractor error-type erroneous-inference plausibility 0.5 targets ["q1"]
509
+ text "Mara is waiting for her brother to join her."
510
+ rationale "Invents a goal the passage never states." cites ["e2"] {}
511
+ claim id "c6" status distractor error-type faulty-reasoning plausibility 0.45 targets ["q1"]
512
+ text "Because Mara is quiet, she must be upset."
513
+ rationale "Treats quiet as upset without textual support." cites ["e2"] {}
514
+ ]
515
+ evidence [
516
+ /* `line` = the paragraph; `quote` = the exact supporting sentence shown as the Part B option */
517
+ source id "e1" line 1 quote "Mara crouched at the edge of the tide pool, ignoring the picnic behind her." status directly-supports supports ["c1"] {}
518
+ source id "e2" line 1 quote "Her brother called twice, but she did not turn around." status supports-wrong-claim supports ["c1" "c2"] {}
519
+ source id "e3" line 1 quote "A tiny crab scuttled under a rock, and Mara smiled for the first time all day." status directly-supports supports ["c1"] {}
520
+ ]
521
+ outcomes [
522
+ outcome id "q1" type ebsr dimension character subject "Mara" standard rl-1 focus "c1"
523
+ stem "Which of these inferences about Mara is supported by the passage?"
524
+ stem-b "Which sentence(s) from the passage best support your answer in Part A?" {}
525
+ ]
526
+ {}..
527
+ ```