@izkac/forgekit 0.3.11 → 0.3.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
package/src/score.mjs
CHANGED
|
@@ -154,11 +154,13 @@ function scoreProductLoopBody(body, executedGreen = false) {
|
|
|
154
154
|
notes.push('no executed green e2e run and no product-loop section in verify-evidence');
|
|
155
155
|
return { points: 0, max, notes };
|
|
156
156
|
}
|
|
157
|
-
|
|
157
|
+
// \w* suffixes: a trailing \b silently rejected inflected forms ("asserts",
|
|
158
|
+
// "fixtures", "ratify") and cost honest sessions real points.
|
|
159
|
+
if (/\b(fixture\w*|OP\d+|testdata\w*|sample\w*)/i.test(body)) {
|
|
158
160
|
pts += 4;
|
|
159
161
|
notes.push('names a fixture / corpus');
|
|
160
162
|
}
|
|
161
|
-
if (/\b(differ
|
|
163
|
+
if (/\b(differ\w*|baseline\w*|ratif\w*|assert\w*|before.?after|output changed)/i.test(body)) {
|
|
162
164
|
pts += 5;
|
|
163
165
|
notes.push('asserts decision/output change vs baseline');
|
|
164
166
|
} else {
|
package/src/score.test.mjs
CHANGED
|
@@ -179,6 +179,32 @@ Fixture: OP1086
|
|
|
179
179
|
}
|
|
180
180
|
});
|
|
181
181
|
|
|
182
|
+
test('scoreSession: product-loop bonuses match inflected forms (asserts, fixtures, ratify)', () => {
|
|
183
|
+
const root = tmp('forge-score-inflect-');
|
|
184
|
+
try {
|
|
185
|
+
const { sessionDir, session } = makeSession(root, { slug: 'jobs-loop' });
|
|
186
|
+
fs.writeFileSync(
|
|
187
|
+
path.join(sessionDir, 'spine.json'),
|
|
188
|
+
`${JSON.stringify(validSpine([validRow()]), null, 2)}\n`,
|
|
189
|
+
'utf8',
|
|
190
|
+
);
|
|
191
|
+
// Every keyword deliberately inflected — a trailing \b used to reject all of these.
|
|
192
|
+
fs.writeFileSync(
|
|
193
|
+
path.join(sessionDir, 'verify-evidence.md'),
|
|
194
|
+
'# Verify\n\n## Product loop\n\n1. seed fixtures\n2. run the loop\n3. asserts the ratify output differs from stored baselines\n',
|
|
195
|
+
'utf8',
|
|
196
|
+
);
|
|
197
|
+
const card = scoreSession({ cwd: root, sessionDir, session });
|
|
198
|
+
const loop = card.checks.find((c) => c.id === 'product_loop');
|
|
199
|
+
const notes = loop.notes.join('\n');
|
|
200
|
+
assert.match(notes, /names a fixture/);
|
|
201
|
+
assert.match(notes, /asserts decision\/output change/);
|
|
202
|
+
assert.equal(loop.points, 20);
|
|
203
|
+
} finally {
|
|
204
|
+
fs.rmSync(root, { recursive: true, force: true });
|
|
205
|
+
}
|
|
206
|
+
});
|
|
207
|
+
|
|
182
208
|
test('scoreSession: green e2e run proves the loop even without the phrase', () => {
|
|
183
209
|
const root = tmp('forge-score-e2e-');
|
|
184
210
|
try {
|
|
@@ -163,6 +163,13 @@ forge defer resolve --task <id> # when the wiring task actually lands
|
|
|
163
163
|
- `forge phase done|finish` **refuses** while any deferral is unresolved.
|
|
164
164
|
- An unregistered "later" in a brief or review is a REJECT.
|
|
165
165
|
|
|
166
|
+
**Prose caveats don't survive — checkboxes and deferrals do.** Never tick a
|
|
167
|
+
`tasks.md` box while a note says the work is unproven ("gate was never taken",
|
|
168
|
+
"not yet verified", "should work"). Scorers, gates, and future sessions see
|
|
169
|
+
the `[x]`, not the sentence above it. If a task is incomplete in any way, the
|
|
170
|
+
box **stays open** or the gap becomes a `forge defer` entry — a ticked box
|
|
171
|
+
documenting its own incompleteness is worse than an open one.
|
|
172
|
+
|
|
166
173
|
## Spine matrix (mechanical — `forge spine`)
|
|
167
174
|
|
|
168
175
|
**Spine is mandatory for every Forge change** — not gated on pace, and not
|