@golden-frijoles/kit 0.14.0 → 0.15.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.
@@ -44,6 +44,7 @@ import {
44
44
  STATE_CHAR_BUDGET,
45
45
  } from './lib/jev.mjs';
46
46
  import { needSetting } from './lib/config.mjs';
47
+ import { loadQuestions, wireQuestion } from './lib/jev-questions.mjs';
47
48
 
48
49
  export const EXIT_SCORED = 0;
49
50
  export const EXIT_USAGE = 1;
@@ -73,90 +74,18 @@ export const ROUTES = Object.freeze({
73
74
  });
74
75
 
75
76
  /**
76
- * EVERY question this script (and the reader at the lock) asks Jev, in one object (D13), so `compiled-prompts` can
77
- * move it to a data file unchanged. `{item}` is replaced by the backticked state path of the claim or criterion
78
- * being asked about (`claims.c3`, `criteria.a2`) — the item's text is in the state, never in the question.
79
- *
80
- * MEASURED, not guessed (D15) — on the 37 labelled items of jev-eval's `intent` set (2026-09-29, jev-1.13.0; five
81
- * pitches, two of them anonymised from a consuming project). "Right" = the yes/no at 0.5 matches the label;
82
- * "decided" = the answer sits at P ≤ 0.2 or ≥ 0.8. Re-measure with `node scripts/jev-eval.mjs --live --rail intent`
83
- * before changing a word:
84
- * coverage_in 17 items · 17 right · 16 decided, all right.
85
- * coverage_out 8 items · 8 right · 6 decided, all right. The first wording ("does this check trace back to a
86
- * claim?") was also 8/8 right but decided only 4: a check on a DETAIL of a claim (a field's
87
- * validation) sat at 0.47–0.51. Naming "a detail of how the plan delivers it" fixed that.
88
- * clarity 12 items · 12 right · 10 decided, all right (score ÷ 3, split at 0.5).
89
- * route not measured: a route is a suggestion for the next artifact, never part of the score.
90
- * Re-running the same request moved one clarity answer across the 0.8 line (0.79 ↔ 0.81): "decided" counts are ±1.
77
+ * EVERY question this script (and the reader at the lock) asks Jev (D13) — now DATA in `lib/jev-questions/intent.json`
78
+ * (compiled-prompts D7), each with its measurement beside it. `{item}` is replaced by the backticked state path of the
79
+ * claim or criterion being asked about (`claims.c3`, `criteria.a2`) — the item's text is in the state, never in the
80
+ * question. Wording history worth keeping: coverage_out's first wording ("does this check trace back to a claim?") was
81
+ * as right but decided only 4 of 8 — a check on a DETAIL of a claim sat at 0.47–0.51 until the question named "a
82
+ * detail of how the plan delivers it". Re-running one request moved a clarity answer across 0.8 (0.79 ↔ 0.81), so
83
+ * "decided" counts are ±1. A recording pins the wording by hash: re-measure with
84
+ * `node scripts/jev-eval.mjs --live --rail intent` after changing a word.
91
85
  */
92
- export const INTENT_QUESTIONS = Object.freeze({
93
- coverage_in: {
94
- type: 'noul',
95
- instructions:
96
- '`pitch` is a plan written in answer to a request. `{item}` is one thing the requester asked for. Does the plan deliver it — is there a part, story, decision or acceptance check in `pitch` that satisfies it, even in different words?',
97
- criteria: {
98
- true: 'Yes: something the plan proposes to build, decide, write or check delivers this requirement, fully or in substance.',
99
- false:
100
- 'No: the plan does not deliver it — it is missing, only restated as background or as the problem, deferred to later work, cut, or listed as out of scope.',
101
- },
102
- },
103
- coverage_out: {
104
- type: 'noul',
105
- instructions:
106
- '`{item}` is an acceptance check from the plan in `pitch`. `claims` lists what the requester asked for. Is this check there because of the request: does it test something a claim asks for, or a detail of how the plan delivers it, or a call the plan records the requester making?',
107
- criteria: {
108
- true: 'Yes: it tests something a claim asks for, or a detail of delivering it (a limit, an error message, a format, a step), or a decision the plan says the requester made.',
109
- false:
110
- 'No: it tests a feature or outcome that no claim asks for and no recorded decision of the requester explains, so it is scope the plan added on its own.',
111
- },
112
- },
113
- clarity: {
114
- type: 'score',
115
- instructions:
116
- '`{item}` is an acceptance check from the plan in `pitch`. Could two builders, working separately, test it the same way and agree whether it passes?',
117
- criteria: [
118
- 'No: it states an aim or a quality ("works well", "is clear", "feels fast") with nothing anyone could observe.',
119
- 'Barely: it names what to look at, but not what counts as passing, so two testers would likely disagree.',
120
- 'Mostly: it names an action and an outcome but leaves one thing to judgement, such as a threshold, a wording or which case to try.',
121
- 'Yes: it names the action, where to do it and the exact result to observe, so two testers would agree.',
122
- ],
123
- },
124
- agreement: {
125
- // Asked by intent-reader.mjs at the architecture lock (D16), once per epic, only when `intent.reader` is on.
126
- // Not measured: there is no labelled set of reader replies yet. Its answer is one signal among five, advisory.
127
- type: 'noul',
128
- instructions:
129
- '`plan` is the architecture lock a builder wrote for this work. `reading` is what a second reader, given only the pitch, says they would build, would not build, and would ask first. Would the two of them build the same thing?',
130
- criteria: {
131
- true: 'Yes: the reading describes the same product and the same scope as the plan; the differences are wording, order, or detail the plan already settles.',
132
- false:
133
- 'No: the reading would build something the plan does not, leave out something the plan builds, or its first question exposes a decision the plan has not made.',
134
- },
135
- },
136
- route: {
137
- type: 'choice',
138
- instructions:
139
- '`{item}` is a gap between the request and the plan in `pitch`: {gap}. Which ONE artifact, made next, would close this gap fastest?',
140
- criteria: {
141
- copy_deck:
142
- 'The exact words a person will read (labels, messages, names, an email) are what is missing or unclear.',
143
- wireframe: 'A screen or page someone uses: what is on it, in what order, and what they can do there.',
144
- flow: 'A journey of several steps: the order of the steps and the branches between them.',
145
- data_sample:
146
- 'A new record, table, file or payload: three real-looking rows would settle what it holds.',
147
- state_machine:
148
- 'A lifecycle: the statuses something moves through and what moves it from one to the next.',
149
- sequence:
150
- 'Calls between services, background work or retries: who calls whom, in what order, and what happens on failure.',
151
- container_diagram:
152
- 'A new repo, package, service or deploy boundary: what runs where and what talks to what.',
153
- spike:
154
- 'A technical unknown: nobody knows yet whether or how it can be done, and a short experiment would answer it.',
155
- think_chain:
156
- 'A judgement or trade-off that needs reasoning through in writing, which none of the other artifacts would settle.',
157
- },
158
- },
159
- });
86
+ export const INTENT_QUESTIONS = Object.freeze(
87
+ Object.fromEntries(loadQuestions('intent').map((q) => [q.id, wireQuestion(q)]))
88
+ );
160
89
 
161
90
  // ── Parsing the seed (D9) ─────────────────────────────────────────────────────────────────────────────────────
162
91