eklavya 1.47.3 → 1.47.4

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.
@@ -27,6 +27,7 @@ yourself thinking one, the right-hand column is what is actually happening.
27
27
  | "I'll reword the question they got wrong." | A question in `asked_before` is spent, not recyclable. |
28
28
  | "A definition is the transferable version of this." | `concept` focus wants the general rule. "What is X" is tier-1 recall wearing a hat. |
29
29
  | "Too easy to be worth asking — I'll add a 'why'." | `easy` is tiers 1–2 and it was earned. A smuggled "why" is a question they cannot answer honestly. |
30
+ | "They know what 'Task 6' means." | They saw none of it. Define the name or drop it. |
30
31
  | "I'll put the dials above the stem for context." | The dials are in the status bar. A line you assemble is one the server cannot keep consistent. |
31
32
  | "Grade 5 — they picked the right option." | Multiple choice caps at 4. One in four is a coin. |
32
33
 
@@ -50,7 +50,9 @@ The code is the subject. Name the file, the line, the decision.
50
50
  The same subject matter, asked so the answer transfers to a different codebase.
51
51
  **This does not mean textbook questions.** The diff stops being the *subject*
52
52
  and becomes the *motivation*: open from what was just written, then ask for the
53
- general rule, the class of problem, or where else it applies.
53
+ general rule, the class of problem, or where else it applies. Open from it in
54
+ words the learner can follow without having read it — they usually have not
55
+ (`writing-mcq.md`, *Write for a cold reader*).
54
56
 
55
57
  - Right: *"We gave the profile cache a 60s TTL in `profile.ts`. TTL is one
56
58
  answer to cache invalidation — what problem is it actually solving, and what
@@ -114,6 +114,23 @@ it rebuilds footing. If they want to stop, they will say so; wait to be told.
114
114
  **Never dump the remaining answers as a list.** If the quiz ends early, it ends.
115
115
  A wall of four explanations at the door is not teaching, it is a receipt.
116
116
 
117
+ ## When they say the question lacks context
118
+
119
+ "This question does not have enough context" is a verdict on the question, not
120
+ a decline. The question assumed something they never saw, so the miss is
121
+ yours. Never drop it untaught:
122
+
123
+ 1. **Own it** in a few words — the question leaned on something you had not
124
+ shown them.
125
+ 2. **Give the answer and one line of why**, defining the name or situation the
126
+ stem skipped.
127
+ 3. **Record it as a blank**: `grade: 0`, `outcome: "dont_know"`, with that
128
+ answer in `feedback`. It is not `declined` — a decline is never offered
129
+ again, and they did not ask to be left alone.
130
+
131
+ The next question about it, now or later, starts with the situation sentence
132
+ the first one was missing (`writing-mcq.md`, *Write for a cold reader*).
133
+
117
134
  ## `already_taught`
118
135
 
119
136
  When it is true on a plan item, they blanked on this before and you explained
@@ -3,16 +3,54 @@
3
3
  Required reading before you write a question. `SKILL.md` decides *whether* to
4
4
  ask and *at what tier*; this is how to build the thing itself.
5
5
 
6
+ ## Write for a cold reader
7
+
8
+ Assume the learner saw none of it: not the code, not the plan, not the task
9
+ list, not the conversation. A background agent usually writes the code, so the
10
+ diff you are looking at is one they have never opened. The question has to work
11
+ from the stem and the four options alone.
12
+
13
+ - **Every project-specific name gets a defining clause, or goes.** "Task 6",
14
+ "the brief", "the plan", "the island", a component nickname, a file they never
15
+ opened: each one is a puzzle the learner must solve before the real question.
16
+ Say what it is — *"the hook that runs when a session starts"* — or ask
17
+ without it.
18
+ - **The key follows from the concept, never from something only you
19
+ observed.** A finding in a write-up they never read, the data from one
20
+ session, your own experiment, the keyframes in a file they never opened: a
21
+ question whose answer depends on these is unfair, not hard.
22
+ - **Situations beat abstractions.** A stem with no host, no situation and no
23
+ example cannot be placed. Name the setting in plain words.
24
+ - **Drop the name, keep the constraint.** The project's details are often what
25
+ made the key the only right answer: *no stored state*, *runs on every prompt*,
26
+ *one writer*. When you replace a name with a general situation, carry those
27
+ constraints into it, or a distractor that was wrong in the project becomes
28
+ right in the abstract.
29
+
30
+ > Opaque: *Task 6 moves the instruction from SessionStart to UserPromptSubmit.
31
+ > What does that change?*
32
+ >
33
+ > Cold: *A Claude Code hook can inject text once when a session starts, or on
34
+ > every prompt the user sends. Why move a reminder to the per-prompt hook?*
35
+
6
36
  ## Build it in this order
7
37
 
8
38
  Six parts, then the call. Build them in the order below — not the order they
9
39
  appear on screen — because each one constrains the next.
10
40
 
11
- **1. The stem.** One question about one idea, in about 25 words, grounded per
12
- the plan's `framing`. Ordinary words: "sent with the request" rather than
13
- "transmitted alongside the request context". Expand an acronym the first time it
14
- appears for this learner — CSRF once, then CSRF. The answer lives in the
15
- options, so the stem asks and stops.
41
+ **1. The stem.** Two parts, grounded per the plan's `framing`:
42
+
43
+ - **The situation** — one plain sentence of 25 words or fewer, saying what is
44
+ happening and defining any name the question uses. One sentence, not two:
45
+ if it will not fit, the question is carrying more setup than one idea needs.
46
+ Leave it out when the question already stands on its own.
47
+ - **The question** — one question about one idea, 25 words or fewer. The
48
+ answer lives in the options, so the question asks and stops.
49
+
50
+ Ordinary words: "sent with the request" rather than "transmitted alongside the
51
+ request context". Expand an acronym the first time it appears for this learner —
52
+ CSRF once, then CSRF. The situation sets the scene and never hints at the
53
+ answer.
16
54
 
17
55
  Ask the positive form, and ask it once: negation makes the stem a reading test
18
56
  rather than a question about the idea, and a stem needing a second clause to be
@@ -23,6 +61,12 @@ precise is doing two jobs — ask the first one and keep the other for later.
23
61
  **2. The correct option.** Write it before the distractors. It sets the length
24
62
  and the grammar the other three have to match.
25
63
 
64
+ Each option is a complete claim on its own: read alone, it says something that
65
+ is true or false. "Re-point from an ancestor" or "How often, and how recent" is
66
+ a riddle, not an option. When the options differ in length, meet parity by
67
+ lengthening the short ones, never by cutting every option down until none of
68
+ them says anything.
69
+
26
70
  **3. Three distractors**, each drawn from one of these:
27
71
 
28
72
  | Source | Written against the stem above |
@@ -92,8 +136,14 @@ quietly drops one of its fields is the other case, and it is what
92
136
  Read yours against this. Each line is a property of the question, so a "no" is
93
137
  telling you which part to rebuild.
94
138
 
95
- - The stem asks one thing, and it fits in one breath.
139
+ - Someone who saw none of the code, plan or conversation could answer it: every
140
+ project-specific name is defined, and the key follows from the concept.
141
+ - The stem asks one thing: at most one sentence of situation, then a question,
142
+ each 25 words or fewer.
143
+ - Read without the project, every wrong option is still wrong: the situation
144
+ kept the constraints the names carried.
96
145
  - The answer appears among the options and nowhere in the stem.
146
+ - Each option is a complete claim when read on its own.
97
147
  - All four options are within a few words of the same length and use the same
98
148
  grammar. A visibly longer or more careful option reads as the correct one, and
99
149
  gets picked without engaging — the same leak as always answering first.
@@ -63,8 +63,34 @@ export function longestSharedRun(a, b) {
63
63
  }
64
64
  return best;
65
65
  }
66
- /** Stems this long stop being read and start being pattern-matched. */
66
+ /**
67
+ * The question sentence: this long and it stops being read and starts being
68
+ * pattern-matched.
69
+ */
67
70
  export const STEM_WORD_LIMIT = 25;
71
+ /**
72
+ * The situation that may come before the question. A stem is one plain
73
+ * sentence of setup and then the question, because a learner who never saw the
74
+ * code needs somewhere to be told what "the plan" or "this hook" is. Before
75
+ * this existed, the single 25-word limit squeezed that setup into a bare name.
76
+ */
77
+ export const SETUP_WORD_LIMIT = 25;
78
+ /**
79
+ * A stem split into its setup and the question that ends it.
80
+ *
81
+ * The question is the last sentence; everything before it is setup. Sentences
82
+ * end at `.`, `!` or `?` followed by whitespace, so `auth.ts` and `res.json()`
83
+ * stay whole.
84
+ */
85
+ export function splitStem(stem) {
86
+ const sentences = stem
87
+ .trim()
88
+ .split(/(?<=[.!?])\s+/)
89
+ .filter((s) => s.length > 0);
90
+ if (sentences.length <= 1)
91
+ return { setup: '', question: stem.trim() };
92
+ return { setup: sentences.slice(0, -1).join(' '), question: sentences[sentences.length - 1] };
93
+ }
68
94
  /** A shared run this long means the stem contains the answer's sentence. */
69
95
  export const ANSWER_RUN_LIMIT = 4;
70
96
  /**
@@ -128,8 +154,10 @@ export function checkQuestion(q) {
128
154
  push('answer_at_position', obeyed, obeyed
129
155
  ? `correct option at ${q.answer_position}, as asked`
130
156
  : `plan said ${q.answer_position}, model used ${q.correct}`);
131
- const stemWords = words(q.stem).length;
132
- push('stem_length', stemWords <= STEM_WORD_LIMIT, `${stemWords} words (limit ${STEM_WORD_LIMIT})`);
157
+ const { setup, question } = splitStem(q.stem);
158
+ const setupWords = words(setup).length;
159
+ const questionWords = words(question).length;
160
+ push('stem_length', setupWords <= SETUP_WORD_LIMIT && questionWords <= STEM_WORD_LIMIT, `setup ${setupWords} words (limit ${SETUP_WORD_LIMIT}), question ${questionWords} words (limit ${STEM_WORD_LIMIT})`);
133
161
  // Indexed into `q.options`, never `labels`. `labels` drops empty options, so
134
162
  // one blank before the answer shifts every later index by one -- and the
135
163
  // conspicuousness check below then compared the correct option against
@@ -1 +1 @@
1
- {"version":3,"file":"question-checks.js","sourceRoot":"","sources":["../../src/eval/question-checks.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"question-checks.js","sourceRoot":"","sources":["../../src/eval/question-checks.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "eklavya",
3
3
  "displayName": "Eklavya",
4
- "version": "1.47.3",
4
+ "version": "1.47.4",
5
5
  "description": "Learn while your agent works. Turns coding-agent generation time into adaptive, Socratic learning grounded in the code being written.",
6
6
  "author": {
7
7
  "name": "Ajay Kumar"
@@ -72,13 +72,15 @@ The implementation is happening in files you can read. Use `Read` and `Grep` to
72
72
 
73
73
  Do not guess at code you have not read. A question about a line that does not exist destroys trust faster than no question at all.
74
74
 
75
+ You read the code; the developer usually has not. Write every question for a reader who saw none of the code, the plan or the conversation: give each project-specific name a defining clause or drop it, and make sure the right answer follows from the concept, not from something only you looked at. `writing-mcq.md`, *Write for a cold reader*, has the rule. If they reply that a question lacks context, give the answer and one line of why, and record it as `dont_know` — `grading.md` has the steps.
76
+
75
77
  ## Session
76
78
 
77
79
  You share the knowledge database with the session that spawned you. Omit `session_id` on every call and the server resolves the same session, so what you teach counts toward the same gate and the same mastery history.
78
80
 
79
81
  ## Pacing
80
82
 
81
- You are competing for attention with an agent that is producing code. Ask one question, then wait. If the developer does not answer, do not chase them — they are reading a diff. Silence is a legitimate answer and costs nothing.
83
+ You are competing for attention with an agent that is producing code. Ask one question, then wait. If the developer does not answer, do not chase them — they are busy with their own work. Silence is a legitimate answer and costs nothing.
82
84
 
83
85
  Never record a grade for a question that was not answered. Record a decline (`outcome: "declined"`) only when they actually say so.
84
86
 
@@ -27,6 +27,7 @@ yourself thinking one, the right-hand column is what is actually happening.
27
27
  | "I'll reword the question they got wrong." | A question in `asked_before` is spent, not recyclable. |
28
28
  | "A definition is the transferable version of this." | `concept` focus wants the general rule. "What is X" is tier-1 recall wearing a hat. |
29
29
  | "Too easy to be worth asking — I'll add a 'why'." | `easy` is tiers 1–2 and it was earned. A smuggled "why" is a question they cannot answer honestly. |
30
+ | "They know what 'Task 6' means." | They saw none of it. Define the name or drop it. |
30
31
  | "I'll put the dials above the stem for context." | The dials are in the status bar. A line you assemble is one the server cannot keep consistent. |
31
32
  | "Grade 5 — they picked the right option." | Multiple choice caps at 4. One in four is a coin. |
32
33
 
@@ -50,7 +50,9 @@ The code is the subject. Name the file, the line, the decision.
50
50
  The same subject matter, asked so the answer transfers to a different codebase.
51
51
  **This does not mean textbook questions.** The diff stops being the *subject*
52
52
  and becomes the *motivation*: open from what was just written, then ask for the
53
- general rule, the class of problem, or where else it applies.
53
+ general rule, the class of problem, or where else it applies. Open from it in
54
+ words the learner can follow without having read it — they usually have not
55
+ (`writing-mcq.md`, *Write for a cold reader*).
54
56
 
55
57
  - Right: *"We gave the profile cache a 60s TTL in `profile.ts`. TTL is one
56
58
  answer to cache invalidation — what problem is it actually solving, and what
@@ -114,6 +114,23 @@ it rebuilds footing. If they want to stop, they will say so; wait to be told.
114
114
  **Never dump the remaining answers as a list.** If the quiz ends early, it ends.
115
115
  A wall of four explanations at the door is not teaching, it is a receipt.
116
116
 
117
+ ## When they say the question lacks context
118
+
119
+ "This question does not have enough context" is a verdict on the question, not
120
+ a decline. The question assumed something they never saw, so the miss is
121
+ yours. Never drop it untaught:
122
+
123
+ 1. **Own it** in a few words — the question leaned on something you had not
124
+ shown them.
125
+ 2. **Give the answer and one line of why**, defining the name or situation the
126
+ stem skipped.
127
+ 3. **Record it as a blank**: `grade: 0`, `outcome: "dont_know"`, with that
128
+ answer in `feedback`. It is not `declined` — a decline is never offered
129
+ again, and they did not ask to be left alone.
130
+
131
+ The next question about it, now or later, starts with the situation sentence
132
+ the first one was missing (`writing-mcq.md`, *Write for a cold reader*).
133
+
117
134
  ## `already_taught`
118
135
 
119
136
  When it is true on a plan item, they blanked on this before and you explained
@@ -3,16 +3,54 @@
3
3
  Required reading before you write a question. `SKILL.md` decides *whether* to
4
4
  ask and *at what tier*; this is how to build the thing itself.
5
5
 
6
+ ## Write for a cold reader
7
+
8
+ Assume the learner saw none of it: not the code, not the plan, not the task
9
+ list, not the conversation. A background agent usually writes the code, so the
10
+ diff you are looking at is one they have never opened. The question has to work
11
+ from the stem and the four options alone.
12
+
13
+ - **Every project-specific name gets a defining clause, or goes.** "Task 6",
14
+ "the brief", "the plan", "the island", a component nickname, a file they never
15
+ opened: each one is a puzzle the learner must solve before the real question.
16
+ Say what it is — *"the hook that runs when a session starts"* — or ask
17
+ without it.
18
+ - **The key follows from the concept, never from something only you
19
+ observed.** A finding in a write-up they never read, the data from one
20
+ session, your own experiment, the keyframes in a file they never opened: a
21
+ question whose answer depends on these is unfair, not hard.
22
+ - **Situations beat abstractions.** A stem with no host, no situation and no
23
+ example cannot be placed. Name the setting in plain words.
24
+ - **Drop the name, keep the constraint.** The project's details are often what
25
+ made the key the only right answer: *no stored state*, *runs on every prompt*,
26
+ *one writer*. When you replace a name with a general situation, carry those
27
+ constraints into it, or a distractor that was wrong in the project becomes
28
+ right in the abstract.
29
+
30
+ > Opaque: *Task 6 moves the instruction from SessionStart to UserPromptSubmit.
31
+ > What does that change?*
32
+ >
33
+ > Cold: *A Claude Code hook can inject text once when a session starts, or on
34
+ > every prompt the user sends. Why move a reminder to the per-prompt hook?*
35
+
6
36
  ## Build it in this order
7
37
 
8
38
  Six parts, then the call. Build them in the order below — not the order they
9
39
  appear on screen — because each one constrains the next.
10
40
 
11
- **1. The stem.** One question about one idea, in about 25 words, grounded per
12
- the plan's `framing`. Ordinary words: "sent with the request" rather than
13
- "transmitted alongside the request context". Expand an acronym the first time it
14
- appears for this learner — CSRF once, then CSRF. The answer lives in the
15
- options, so the stem asks and stops.
41
+ **1. The stem.** Two parts, grounded per the plan's `framing`:
42
+
43
+ - **The situation** — one plain sentence of 25 words or fewer, saying what is
44
+ happening and defining any name the question uses. One sentence, not two:
45
+ if it will not fit, the question is carrying more setup than one idea needs.
46
+ Leave it out when the question already stands on its own.
47
+ - **The question** — one question about one idea, 25 words or fewer. The
48
+ answer lives in the options, so the question asks and stops.
49
+
50
+ Ordinary words: "sent with the request" rather than "transmitted alongside the
51
+ request context". Expand an acronym the first time it appears for this learner —
52
+ CSRF once, then CSRF. The situation sets the scene and never hints at the
53
+ answer.
16
54
 
17
55
  Ask the positive form, and ask it once: negation makes the stem a reading test
18
56
  rather than a question about the idea, and a stem needing a second clause to be
@@ -23,6 +61,12 @@ precise is doing two jobs — ask the first one and keep the other for later.
23
61
  **2. The correct option.** Write it before the distractors. It sets the length
24
62
  and the grammar the other three have to match.
25
63
 
64
+ Each option is a complete claim on its own: read alone, it says something that
65
+ is true or false. "Re-point from an ancestor" or "How often, and how recent" is
66
+ a riddle, not an option. When the options differ in length, meet parity by
67
+ lengthening the short ones, never by cutting every option down until none of
68
+ them says anything.
69
+
26
70
  **3. Three distractors**, each drawn from one of these:
27
71
 
28
72
  | Source | Written against the stem above |
@@ -92,8 +136,14 @@ quietly drops one of its fields is the other case, and it is what
92
136
  Read yours against this. Each line is a property of the question, so a "no" is
93
137
  telling you which part to rebuild.
94
138
 
95
- - The stem asks one thing, and it fits in one breath.
139
+ - Someone who saw none of the code, plan or conversation could answer it: every
140
+ project-specific name is defined, and the key follows from the concept.
141
+ - The stem asks one thing: at most one sentence of situation, then a question,
142
+ each 25 words or fewer.
143
+ - Read without the project, every wrong option is still wrong: the situation
144
+ kept the constraints the names carried.
96
145
  - The answer appears among the options and nowhere in the stem.
146
+ - Each option is a complete claim when read on its own.
97
147
  - All four options are within a few words of the same length and use the same
98
148
  grammar. A visibly longer or more careful option reads as the correct one, and
99
149
  gets picked without engaging — the same leak as always answering first.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eklavya",
3
- "version": "1.47.3",
3
+ "version": "1.47.4",
4
4
  "description": "Learn while your agent works — local knowledge graph, spaced repetition, and quiz gating for agent-assisted development.",
5
5
  "license": "MIT",
6
6
  "repository": {