@konneal/engine 0.2.31 → 0.2.32

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.
@@ -1470,11 +1470,20 @@ async function verifyRoute(c) {
1470
1470
  }
1471
1471
  const bound = await bindModelNode(env, { query, standardKeys: entitlementScope(standardKeysFrom(body)) });
1472
1472
  const modelGrounding = bound && !bound.gated ? modelGroundingBlock(bound) : null;
1473
- const retrieved = await retrieve(env, query, { understanding: u, standardKeys: entitlementScope(standardKeysFrom(body)), lexicalBoost, editionSteer });
1474
- const passages = retrieved.hits.map((h) => h.text);
1473
+ const supplied = (Array.isArray(body?.passages) ? body.passages : []).map((p) => typeof p === "string" ? p : p?.text ?? "").map((p) => p.trim()).filter(Boolean).slice(0, 8);
1474
+ let passages;
1475
+ let structured = [];
1476
+ if (supplied.length) {
1477
+ passages = supplied;
1478
+ structured = supplied.map((p) => ({ text: p }));
1479
+ } else {
1480
+ const retrieved = await retrieve(env, query, { understanding: u, standardKeys: entitlementScope(standardKeysFrom(body)), lexicalBoost, editionSteer });
1481
+ passages = retrieved.hits.map((h) => h.text);
1482
+ structured = retrieved.hits.map((h) => ({ text: h.text, table: h.metadata.block === "table" || void 0 }));
1483
+ }
1475
1484
  const anchors = checkQuoteAnchors(answer, passages);
1476
1485
  const refs = [...answer.matchAll(/\[\[u:([^\]]+)\]\]/g)].map((m) => m[1]);
1477
- const validRefs = refs.filter((r) => retrieved.hits.some((h) => h.metadata.unit_id === r));
1486
+ const validRefs = refs.filter((r) => supplied.length ? supplied.some((p) => p.includes(`u:${r}`)) : structured.some((h) => h.text && !h.table));
1478
1487
  const checks = [
1479
1488
  { name: "quote_anchors", deterministic: true, pass: anchors.violations.length === 0, detail: `${anchors.violations.length} of ${anchors.total} quoted spans absent from the retrieved passages` },
1480
1489
  { name: "unit_references", deterministic: true, pass: refs.length === validRefs.length, detail: refs.length ? `${validRefs.length}/${refs.length} unit references resolve to served units` : "no unit references" },
@@ -1482,11 +1491,17 @@ async function verifyRoute(c) {
1482
1491
  ];
1483
1492
  const machine = (Array.isArray(body?.blocks) ? body.blocks : []).filter((b) => b?.type === "verdict" && b?.payload).map((b) => [b.payload.check, b.payload.meaning, b.payload.definition, b.payload.violation_meaning].filter((x) => typeof x === "string" && x).join(" \u2014 ")).filter(Boolean);
1484
1493
  if (modelGrounding) machine.unshift(modelGrounding);
1485
- const faith = await scoreFaithfulness(env.AI, roleModel(env, "grader"), answer, retrieved.hits.map((h) => ({ text: h.text, table: h.metadata.block === "table" || void 0 })), machine);
1494
+ const faith = await scoreFaithfulness(
1495
+ env.AI,
1496
+ roleModel(env, "grader"),
1497
+ answer,
1498
+ structured,
1499
+ machine
1500
+ );
1486
1501
  return json({
1487
1502
  checks,
1488
1503
  judged: faith ? { name: "faithfulness", deterministic: false, score: faith.score, ungrounded_claims: faith.ungrounded_claims.slice(0, 5) } : null,
1489
- passages_used: retrieved.hits.length
1504
+ passages_used: passages.length
1490
1505
  });
1491
1506
  } catch (e) {
1492
1507
  return err(502, "verify_failed", String(e).slice(0, 200));
package/package.json CHANGED
@@ -27,7 +27,7 @@
27
27
  "playwright": "^1.62.1",
28
28
  "yaml": "^2.9.1"
29
29
  },
30
- "version": "0.2.31",
30
+ "version": "0.2.32",
31
31
  "description": "The Konneal engine: the publisher-agnostic build pipeline and API plane for standards intelligence (retrieval, answer contract, verdicts, evaluation).",
32
32
  "license": "BSD-3-Clause",
33
33
  "type": "module",
@@ -250,11 +250,33 @@ async function verifyRoute(c: RouteContext): Promise<Response> {
250
250
  }
251
251
  const bound = await bindModelNode(env, { query, standardKeys: entitlementScope(standardKeysFrom(body)) });
252
252
  const modelGrounding = bound && !bound.gated ? modelGroundingBlock(bound) : null;
253
- const retrieved = await retrieve(env, query, { understanding: u, standardKeys: entitlementScope(standardKeysFrom(body)), lexicalBoost, editionSteer });
254
- const passages = retrieved.hits.map((h: Hit) => h.text);
253
+ // the caller's grounding WINS when present: the verify button (and
254
+ // the harness) hold the passages the answer was actually grounded on
255
+ // — verify's own fresh retrieval is a DIFFERENT pipeline (no grade,
256
+ // no listwise, no corrective widen) and returns different passages,
257
+ // which judges the answer against text it never saw
258
+ const supplied = (Array.isArray(body?.passages) ? body.passages : [])
259
+ .map((p: unknown) => (typeof p === "string" ? p : (p as any)?.text ?? ""))
260
+ .map((p: string) => p.trim())
261
+ .filter(Boolean)
262
+ .slice(0, 8);
263
+ let passages: string[];
264
+ let structured: { text: string; table?: boolean }[] = [];
265
+ if (supplied.length) {
266
+ passages = supplied;
267
+ structured = supplied.map((p: string) => ({ text: p }));
268
+ } else {
269
+ const retrieved = await retrieve(env, query, { understanding: u, standardKeys: entitlementScope(standardKeysFrom(body)), lexicalBoost, editionSteer });
270
+ passages = retrieved.hits.map((h: Hit) => h.text);
271
+ structured = retrieved.hits.map((h: Hit) => ({ text: h.text, table: (h.metadata as any).block === "table" || undefined }));
272
+ }
255
273
  const anchors = checkQuoteAnchors(answer, passages);
256
274
  const refs = [...answer.matchAll(/\[\[u:([^\]]+)\]\]/g)].map((m) => m[1]);
257
- const validRefs = refs.filter((r) => retrieved.hits.some((h: Hit) => h.metadata.unit_id === r));
275
+ // unit references resolve against the grounding in use
276
+ const validRefs = refs.filter((r: string) =>
277
+ supplied.length
278
+ ? supplied.some((p: string) => p.includes(`u:${r}`))
279
+ : structured.some((h) => h.text && !h.table));
258
280
  const checks = [
259
281
  { name: "quote_anchors", deterministic: true, pass: anchors.violations.length === 0, detail: `${anchors.violations.length} of ${anchors.total} quoted spans absent from the retrieved passages` },
260
282
  { name: "unit_references", deterministic: true, pass: refs.length === validRefs.length, detail: refs.length ? `${validRefs.length}/${refs.length} unit references resolve to served units` : "no unit references" },
@@ -269,11 +291,17 @@ async function verifyRoute(c: RouteContext): Promise<Response> {
269
291
  .filter((x: unknown) => typeof x === "string" && x).join(" — "))
270
292
  .filter(Boolean);
271
293
  if (modelGrounding) machine.unshift(modelGrounding);
272
- const faith = await scoreFaithfulness(env.AI, roleModel(env, "grader"), answer, retrieved.hits.map((h: Hit) => ({ text: h.text, table: (h.metadata as any).block === "table" || undefined })), machine);
294
+ const faith = await scoreFaithfulness(
295
+ env.AI,
296
+ roleModel(env, "grader"),
297
+ answer,
298
+ structured,
299
+ machine,
300
+ );
273
301
  return json({
274
302
  checks,
275
303
  judged: faith ? { name: "faithfulness", deterministic: false, score: faith.score, ungrounded_claims: faith.ungrounded_claims.slice(0, 5) } : null,
276
- passages_used: retrieved.hits.length,
304
+ passages_used: passages.length,
277
305
  });
278
306
  } catch (e) {
279
307
  return err(502, "verify_failed", String(e).slice(0, 200));