modelrig 0.8.0 → 0.9.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.
- package/CHANGELOG.md +156 -0
- package/README.md +27 -2
- package/dist/artifacts/artifact.d.ts +12 -13
- package/dist/artifacts/artifact.d.ts.map +1 -1
- package/dist/artifacts/artifact.js +17 -23
- package/dist/artifacts/index.d.ts +13 -5
- package/dist/artifacts/index.d.ts.map +1 -1
- package/dist/artifacts/index.js +11 -4
- package/dist/artifacts/run-context.d.ts +3 -24
- package/dist/artifacts/run-context.d.ts.map +1 -1
- package/dist/artifacts/run-context.js +3 -39
- package/dist/bakeoff/engine.d.ts +29 -0
- package/dist/bakeoff/engine.d.ts.map +1 -1
- package/dist/bakeoff/engine.js +47 -0
- package/dist/bakeoff/eval-cases-rig.d.ts +36 -0
- package/dist/bakeoff/eval-cases-rig.d.ts.map +1 -0
- package/dist/bakeoff/eval-cases-rig.js +27 -0
- package/dist/bakeoff/eval-cases.d.ts +19 -0
- package/dist/bakeoff/eval-cases.d.ts.map +1 -1
- package/dist/bakeoff/eval-cases.js +18 -1
- package/dist/bakeoff/golden-judge.d.ts +47 -0
- package/dist/bakeoff/golden-judge.d.ts.map +1 -0
- package/dist/bakeoff/golden-judge.js +49 -0
- package/dist/bakeoff/quality.d.ts +30 -0
- package/dist/bakeoff/quality.d.ts.map +1 -1
- package/dist/bakeoff/quality.js +21 -0
- package/dist/bakeoff/replay.d.ts +11 -0
- package/dist/bakeoff/replay.d.ts.map +1 -1
- package/dist/bakeoff/replay.js +8 -0
- package/dist/bakeoff/report.d.ts +7 -0
- package/dist/bakeoff/report.d.ts.map +1 -1
- package/dist/bakeoff/report.js +26 -0
- package/dist/cli-judge.d.ts +12 -0
- package/dist/cli-judge.d.ts.map +1 -0
- package/dist/cli-judge.js +48 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +14 -42
- package/dist/config.d.ts +54 -29
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +86 -47
- package/dist/detect/detector.d.ts +4 -2
- package/dist/detect/detector.d.ts.map +1 -1
- package/dist/detect/safe-harbor.d.ts +57 -0
- package/dist/detect/safe-harbor.d.ts.map +1 -0
- package/dist/detect/safe-harbor.js +278 -0
- package/dist/feedback/coverage.d.ts +11 -8
- package/dist/feedback/coverage.d.ts.map +1 -1
- package/dist/feedback/coverage.js +29 -16
- package/dist/feedback/grade.d.ts +51 -0
- package/dist/feedback/grade.d.ts.map +1 -0
- package/dist/feedback/grade.js +63 -0
- package/dist/gateway/http-protocol.d.ts +1 -1
- package/dist/gateway/http-protocol.d.ts.map +1 -1
- package/dist/gateway/http-protocol.js +1 -1
- package/dist/index.d.ts +44 -27
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +110 -43
- package/dist/init/observe-cli.js +1 -1
- package/dist/init/observe.d.ts +2 -2
- package/dist/init/observe.d.ts.map +1 -1
- package/dist/init/observe.js +11 -7
- package/dist/mask/arm.d.ts +112 -0
- package/dist/mask/arm.d.ts.map +1 -0
- package/dist/mask/arm.js +179 -0
- package/dist/mask/index.d.ts +2 -0
- package/dist/mask/index.d.ts.map +1 -1
- package/dist/mask/index.js +7 -1
- package/dist/mask/mask-policy-cli.d.ts +12 -4
- package/dist/mask/mask-policy-cli.d.ts.map +1 -1
- package/dist/mask/mask-policy-cli.js +34 -9
- package/dist/query/grammar.d.ts +2 -2
- package/dist/query/grammar.d.ts.map +1 -1
- package/dist/query/grammar.js +3 -1
- package/dist/query/saved.d.ts +13 -0
- package/dist/query/saved.d.ts.map +1 -1
- package/dist/query/saved.js +67 -1
- package/dist/receipts/types.d.ts +1 -1
- package/dist/receipts/types.d.ts.map +1 -1
- package/dist/receipts/types.js +1 -0
- package/dist/registry/build.d.ts +43 -1
- package/dist/registry/build.d.ts.map +1 -1
- package/dist/registry/build.js +52 -0
- package/dist/registry/pricing-shape.d.ts +29 -0
- package/dist/registry/pricing-shape.d.ts.map +1 -1
- package/dist/registry/pricing-shape.js +10 -1
- package/dist/registry/rows.d.ts.map +1 -1
- package/dist/registry/rows.js +1 -0
- package/dist/registry/select.d.ts +6 -1
- package/dist/registry/select.d.ts.map +1 -1
- package/dist/registry/select.js +11 -0
- package/dist/routes/call-config.d.ts +199 -0
- package/dist/routes/call-config.d.ts.map +1 -0
- package/dist/routes/call-config.js +343 -0
- package/dist/routes/loader.js +5 -3
- package/dist/routes/objective-loader.d.ts +12 -0
- package/dist/routes/objective-loader.d.ts.map +1 -1
- package/dist/routes/objective-loader.js +82 -0
- package/dist/routes/resolved-bundle.d.ts +50 -0
- package/dist/routes/resolved-bundle.d.ts.map +1 -1
- package/dist/routes/resolved-bundle.js +52 -0
- package/dist/routes/screen-loader.d.ts +28 -0
- package/dist/routes/screen-loader.d.ts.map +1 -1
- package/dist/routes/screen-loader.js +51 -0
- package/dist/run/accept.d.ts +2 -0
- package/dist/run/accept.d.ts.map +1 -1
- package/dist/run/accept.js +1 -0
- package/dist/run/dispatch.d.ts +42 -13
- package/dist/run/dispatch.d.ts.map +1 -1
- package/dist/run/dispatch.js +107 -25
- package/dist/run/grounding.d.ts +28 -2
- package/dist/run/grounding.d.ts.map +1 -1
- package/dist/run/grounding.js +54 -10
- package/dist/run/record-attempt.d.ts +4 -0
- package/dist/run/record-attempt.d.ts.map +1 -1
- package/dist/run/record-attempt.js +4 -0
- package/dist/run/routing-docs.js +1 -1
- package/dist/run/run.d.ts.map +1 -1
- package/dist/run/run.js +21 -26
- package/dist/savings/odometer.d.ts +4 -0
- package/dist/savings/odometer.d.ts.map +1 -1
- package/dist/savings/odometer.js +20 -1
- package/dist/savings/swap-execute.d.ts +7 -0
- package/dist/savings/swap-execute.d.ts.map +1 -1
- package/dist/savings/swap-execute.js +30 -0
- package/dist/savings/swaps-client.d.ts +10 -0
- package/dist/savings/swaps-client.d.ts.map +1 -1
- package/dist/screen/fixtures/probe-corpora.d.ts +23 -0
- package/dist/screen/fixtures/probe-corpora.d.ts.map +1 -0
- package/dist/screen/fixtures/probe-corpora.js +69 -0
- package/dist/screen/index.d.ts +21 -0
- package/dist/screen/index.d.ts.map +1 -0
- package/dist/screen/index.js +64 -0
- package/dist/screen/model-screen.d.ts +111 -0
- package/dist/screen/model-screen.d.ts.map +1 -0
- package/dist/screen/model-screen.js +178 -0
- package/dist/screen/patterns.d.ts +51 -0
- package/dist/screen/patterns.d.ts.map +1 -0
- package/dist/screen/patterns.js +151 -0
- package/dist/screen/phi-gate.d.ts +52 -0
- package/dist/screen/phi-gate.d.ts.map +1 -0
- package/dist/screen/phi-gate.js +86 -0
- package/dist/screen/policy.d.ts +71 -0
- package/dist/screen/policy.d.ts.map +1 -0
- package/dist/screen/policy.js +334 -0
- package/dist/screen/probe.d.ts +118 -0
- package/dist/screen/probe.d.ts.map +1 -0
- package/dist/screen/probe.js +132 -0
- package/dist/screen/screen-cli.d.ts +16 -0
- package/dist/screen/screen-cli.d.ts.map +1 -0
- package/dist/screen/screen-cli.js +178 -0
- package/dist/screen/screen.d.ts +99 -0
- package/dist/screen/screen.d.ts.map +1 -0
- package/dist/screen/screen.js +0 -0
- package/dist/screen/sidecar.d.ts +69 -0
- package/dist/screen/sidecar.d.ts.map +1 -0
- package/dist/screen/sidecar.js +145 -0
- package/dist/screen/types.d.ts +43 -2
- package/dist/screen/types.d.ts.map +1 -1
- package/dist/settings/api-fetcher.d.ts +14 -3
- package/dist/settings/api-fetcher.d.ts.map +1 -1
- package/dist/settings/api-fetcher.js +61 -10
- package/dist/settings/grading-guide.d.ts +76 -0
- package/dist/settings/grading-guide.d.ts.map +1 -0
- package/dist/settings/grading-guide.js +23 -0
- package/dist/settings/index.d.ts +3 -2
- package/dist/settings/index.d.ts.map +1 -1
- package/dist/settings/index.js +2 -1
- package/dist/settings/task-settings.d.ts +44 -7
- package/dist/settings/task-settings.d.ts.map +1 -1
- package/dist/settings/task-settings.js +53 -12
- package/dist/status.d.ts +26 -20
- package/dist/status.d.ts.map +1 -1
- package/dist/status.js +47 -29
- package/dist/telemetry/artifact-store.d.ts +5 -6
- package/dist/telemetry/artifact-store.d.ts.map +1 -1
- package/dist/telemetry/artifact-store.js +10 -24
- package/dist/telemetry/attempt-meta.d.ts +21 -0
- package/dist/telemetry/attempt-meta.d.ts.map +1 -1
- package/dist/telemetry/attempt-meta.js +9 -0
- package/dist/telemetry/exporter.d.ts +2 -2
- package/dist/telemetry/exporter.d.ts.map +1 -1
- package/dist/telemetry/exporter.js +22 -41
- package/dist/telemetry/grade-mappers.d.ts +22 -0
- package/dist/telemetry/grade-mappers.d.ts.map +1 -0
- package/dist/telemetry/grade-mappers.js +58 -0
- package/dist/telemetry/grades-sql.d.ts +53 -0
- package/dist/telemetry/grades-sql.d.ts.map +1 -0
- package/dist/telemetry/grades-sql.js +133 -0
- package/dist/telemetry/ingest-protocol.d.ts +29 -46
- package/dist/telemetry/ingest-protocol.d.ts.map +1 -1
- package/dist/telemetry/ingest-protocol.js +16 -54
- package/dist/telemetry/store-migrations.d.ts.map +1 -1
- package/dist/telemetry/store-migrations.js +51 -0
- package/dist/telemetry/store.d.ts +9 -6
- package/dist/telemetry/store.d.ts.map +1 -1
- package/dist/telemetry/store.js +8 -50
- package/dist/tenancy/api-key-format.d.ts +30 -1
- package/dist/tenancy/api-key-format.d.ts.map +1 -1
- package/dist/tenancy/api-key-format.js +33 -1
- package/dist/types/provider.d.ts +3 -0
- package/dist/types/provider.d.ts.map +1 -1
- package/dist/types/provider.js +25 -0
- package/dist/types/route.d.ts +78 -2
- package/dist/types/route.d.ts.map +1 -1
- package/dist/types/telemetry.d.ts +43 -46
- package/dist/types/telemetry.d.ts.map +1 -1
- package/dist/validate-cli.d.ts.map +1 -1
- package/dist/validate-cli.js +32 -0
- package/dist/verify/verify.d.ts +5 -0
- package/dist/verify/verify.d.ts.map +1 -1
- package/dist/verify/verify.js +2 -0
- package/dist/watch/evaluate.d.ts +84 -1
- package/dist/watch/evaluate.d.ts.map +1 -1
- package/dist/watch/evaluate.js +28 -0
- package/dist/watch/monitor.d.ts +8 -2
- package/dist/watch/monitor.d.ts.map +1 -1
- package/dist/watch/monitor.js +13 -5
- package/dist/watch/regret-monitor-cli.d.ts +16 -0
- package/dist/watch/regret-monitor-cli.d.ts.map +1 -0
- package/dist/watch/regret-monitor-cli.js +137 -0
- package/dist/watch/regret-monitor.d.ts +168 -0
- package/dist/watch/regret-monitor.d.ts.map +1 -0
- package/dist/watch/regret-monitor.js +304 -0
- package/dist/watch/upgrade.d.ts +62 -0
- package/dist/watch/upgrade.d.ts.map +1 -0
- package/dist/watch/upgrade.js +57 -0
- package/docs/agent-skill/SKILL.md +109 -5
- package/docs/how-it-fits.md +3 -2
- package/docs/instrumentation.md +149 -21
- package/docs/llms.txt +64 -20
- package/docs/mcp-oracle.md +249 -0
- package/docs/quickstart.md +103 -9
- package/package.json +16 -3
- package/registry/leaderboard.json +74 -0
- package/registry/registry.json +150 -112
- package/screen.d.ts +16 -0
- package/templates/call-disposition-qa.json +77 -0
- package/templates/catalog-cleansing.json +77 -0
- package/templates/compliance-review.json +76 -0
- package/templates/cs-next-action.json +76 -0
- package/templates/document-extraction.json +78 -0
- package/templates/financial-classification.json +75 -0
- package/templates/lead-qualification.json +76 -0
- package/templates/medical-classification.json +71 -0
- package/templates/ticket-triage.json +76 -0
- package/dist/telemetry/supabase-exporter.d.ts +0 -64
- package/dist/telemetry/supabase-exporter.d.ts.map +0 -1
- package/dist/telemetry/supabase-exporter.js +0 -211
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SC-2 — deterministic HIPAA Safe Harbor identifier detectors (spec-sc2 §2).
|
|
3
|
+
*
|
|
4
|
+
* These EXTEND scrub v1 (S1: extend, don't twin) as new `Detector`s over the
|
|
5
|
+
* shared interface (src/detect/detector.ts) — `kind: "deterministic"`,
|
|
6
|
+
* `confidence: 1`. They live BESIDE scrub v1's five detectors, NOT inside
|
|
7
|
+
* `scrubContent`: adding one here never widens the custody scrub floor. The
|
|
8
|
+
* composition point is the screen policy `detectors: [...]` opt-in — a route
|
|
9
|
+
* turns a Safe Harbor detector on explicitly (spec-sc2 §2, builder confirmation:
|
|
10
|
+
* "never silently added to the custody scrub floor"). `scrubContent` and the
|
|
11
|
+
* five v1 detectors stay BYTE-IDENTICAL (golden).
|
|
12
|
+
*
|
|
13
|
+
* LEAK INVARIANT (spec-sc2 §1.4): a detector emits SPANS (offsets + type +
|
|
14
|
+
* confidence) — never the matched substring. The matched value is read only to
|
|
15
|
+
* validate (Luhn / VIN checksum / octet range / age bound) and is discarded
|
|
16
|
+
* immediately; nothing here returns, logs, or persists it.
|
|
17
|
+
*
|
|
18
|
+
* SCOPE (honest limits, stated in the coverage table): US-English-shaped,
|
|
19
|
+
* deterministic regex/checksum rules — NOT a model, NOT DLP. Free-text names and
|
|
20
|
+
* street addresses need the customer-run sidecar (src/screen/sidecar.ts); those
|
|
21
|
+
* classes are `sidecar`/`out-of-scope` in the coverage table, never claimed here.
|
|
22
|
+
* Recall on synthetic PHI is MEASURED by the SC-3 probe, not asserted here.
|
|
23
|
+
*/
|
|
24
|
+
import type { Detector } from "./detector";
|
|
25
|
+
/** The finding `type` a Safe Harbor detector emits — a `pii:*` COUNT label
|
|
26
|
+
* (spec-sc2 §5), never a value. Kept parallel to the detector `id` slug. */
|
|
27
|
+
export type SafeHarborType = "pii:date" | "pii:age_over_89" | "pii:fax" | "pii:url" | "pii:ip" | "pii:zip" | "pii:account_id" | "pii:license_id" | "pii:vin" | "pii:device_id";
|
|
28
|
+
/** VIN check-digit rule (position 9): weighted transliteration mod 11, where 10
|
|
29
|
+
* ⇒ 'X'. Separates a real VIN from any 17 alphanumerics — the difference between
|
|
30
|
+
* a false-positive flood and a claimable identifier. */
|
|
31
|
+
export declare function vinValid(vin: string): boolean;
|
|
32
|
+
/** The registry id of the convenience PACK — configuring it in a route's
|
|
33
|
+
* `screen.detectors` opts in to ALL ten deterministic Safe Harbor detectors at
|
|
34
|
+
* once. Individual `pii:<slug>@v1` ids opt in to just that one. */
|
|
35
|
+
export declare const SAFE_HARBOR_PACK_ID = "safe-harbor@v1";
|
|
36
|
+
/** All individual Safe Harbor detector ids, for policy validation. */
|
|
37
|
+
export declare const SAFE_HARBOR_IDS: ReadonlySet<string>;
|
|
38
|
+
/** True when `id` names a Safe Harbor detector (a `pii:<slug>@v1` or the pack).
|
|
39
|
+
* The screen policy validator uses this to accept the id at load time. */
|
|
40
|
+
export declare function isSafeHarborId(id: string): boolean;
|
|
41
|
+
/** Every Safe Harbor detector (one per type), for the pack. */
|
|
42
|
+
export declare function safeHarborDetectors(): Detector[];
|
|
43
|
+
/** The Safe Harbor detector for one id, or `undefined` if `id` is not one.
|
|
44
|
+
* `SAFE_HARBOR_PACK_ID` returns `undefined` here — the pack expands to
|
|
45
|
+
* {@link safeHarborDetectors}; a caller resolves the pack separately. */
|
|
46
|
+
export declare function safeHarborDetectorById(id: string): Detector | undefined;
|
|
47
|
+
/** The detector identities (id + version) for a configured id — the pack
|
|
48
|
+
* expands to all ten; a single id resolves to one. Used to populate the
|
|
49
|
+
* receipt's `detectors[]` at resolve time (counts-only, never a value). */
|
|
50
|
+
export declare function safeHarborIdentities(id: string): readonly {
|
|
51
|
+
id: string;
|
|
52
|
+
version: string;
|
|
53
|
+
}[];
|
|
54
|
+
/** Build the Detector instances a configured id contributes (pack ⇒ all ten,
|
|
55
|
+
* single id ⇒ one, unknown ⇒ none). */
|
|
56
|
+
export declare function safeHarborDetectorsFor(id: string): Detector[];
|
|
57
|
+
//# sourceMappingURL=safe-harbor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"safe-harbor.d.ts","sourceRoot":"","sources":["../../src/detect/safe-harbor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,KAAK,EAAiC,QAAQ,EAAE,MAAM,YAAY,CAAC;AAG1E;4EAC4E;AAC5E,MAAM,MAAM,cAAc,GACtB,UAAU,GACV,iBAAiB,GACjB,SAAS,GACT,SAAS,GACT,QAAQ,GACR,SAAS,GACT,gBAAgB,GAChB,gBAAgB,GAChB,SAAS,GACT,eAAe,CAAC;AAoJpB;;wDAEwD;AACxD,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAa7C;AA6CD;;mEAEmE;AACnE,eAAO,MAAM,mBAAmB,mBAAmB,CAAC;AAEpD,sEAAsE;AACtE,eAAO,MAAM,eAAe,EAAE,WAAW,CAAC,MAAM,CAAmC,CAAC;AAEpF;0EAC0E;AAC1E,wBAAgB,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAElD;AA8BD,+DAA+D;AAC/D,wBAAgB,mBAAmB,IAAI,QAAQ,EAAE,CAEhD;AAED;;yEAEyE;AACzE,wBAAgB,sBAAsB,CAAC,EAAE,EAAE,MAAM,GAAG,QAAQ,GAAG,SAAS,CAGvE;AAED;;2EAE2E;AAC3E,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,EAAE,CAG3F;AAED;uCACuC;AACvC,wBAAgB,sBAAsB,CAAC,EAAE,EAAE,MAAM,GAAG,QAAQ,EAAE,CAI7D"}
|
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* SC-2 — deterministic HIPAA Safe Harbor identifier detectors (spec-sc2 §2).
|
|
4
|
+
*
|
|
5
|
+
* These EXTEND scrub v1 (S1: extend, don't twin) as new `Detector`s over the
|
|
6
|
+
* shared interface (src/detect/detector.ts) — `kind: "deterministic"`,
|
|
7
|
+
* `confidence: 1`. They live BESIDE scrub v1's five detectors, NOT inside
|
|
8
|
+
* `scrubContent`: adding one here never widens the custody scrub floor. The
|
|
9
|
+
* composition point is the screen policy `detectors: [...]` opt-in — a route
|
|
10
|
+
* turns a Safe Harbor detector on explicitly (spec-sc2 §2, builder confirmation:
|
|
11
|
+
* "never silently added to the custody scrub floor"). `scrubContent` and the
|
|
12
|
+
* five v1 detectors stay BYTE-IDENTICAL (golden).
|
|
13
|
+
*
|
|
14
|
+
* LEAK INVARIANT (spec-sc2 §1.4): a detector emits SPANS (offsets + type +
|
|
15
|
+
* confidence) — never the matched substring. The matched value is read only to
|
|
16
|
+
* validate (Luhn / VIN checksum / octet range / age bound) and is discarded
|
|
17
|
+
* immediately; nothing here returns, logs, or persists it.
|
|
18
|
+
*
|
|
19
|
+
* SCOPE (honest limits, stated in the coverage table): US-English-shaped,
|
|
20
|
+
* deterministic regex/checksum rules — NOT a model, NOT DLP. Free-text names and
|
|
21
|
+
* street addresses need the customer-run sidecar (src/screen/sidecar.ts); those
|
|
22
|
+
* classes are `sidecar`/`out-of-scope` in the coverage table, never claimed here.
|
|
23
|
+
* Recall on synthetic PHI is MEASURED by the SC-3 probe, not asserted here.
|
|
24
|
+
*/
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.SAFE_HARBOR_IDS = exports.SAFE_HARBOR_PACK_ID = void 0;
|
|
27
|
+
exports.vinValid = vinValid;
|
|
28
|
+
exports.isSafeHarborId = isSafeHarborId;
|
|
29
|
+
exports.safeHarborDetectors = safeHarborDetectors;
|
|
30
|
+
exports.safeHarborDetectorById = safeHarborDetectorById;
|
|
31
|
+
exports.safeHarborIdentities = safeHarborIdentities;
|
|
32
|
+
exports.safeHarborDetectorsFor = safeHarborDetectorsFor;
|
|
33
|
+
const scrub_1 = require("../artifacts/scrub");
|
|
34
|
+
/** Cap on spans emitted per detect() call ("per-result cap", spec-sc2 §2): a
|
|
35
|
+
* pathological document (a table of dates) yields COUNTS, not an unbounded span
|
|
36
|
+
* list. The count is truthful up to the cap; beyond it the receipt reads
|
|
37
|
+
* "≥ cap", which is enough to drive a policy action. */
|
|
38
|
+
const MAX_SPANS_PER_TYPE = 512;
|
|
39
|
+
/** Push a `{start,end,type,confidence:1}` span, capped. The matched value is the
|
|
40
|
+
* caller's local variable; it never enters the span. */
|
|
41
|
+
function emit(spans, type, start, len) {
|
|
42
|
+
if (spans.length >= MAX_SPANS_PER_TYPE)
|
|
43
|
+
return;
|
|
44
|
+
spans.push({ start, end: start + len, type, confidence: 1 });
|
|
45
|
+
}
|
|
46
|
+
/** Iterate global-regex matches with a fresh RegExp (so /g `lastIndex` never
|
|
47
|
+
* leaks across calls), passing each match to `onMatch`. */
|
|
48
|
+
function eachMatch(re, text, onMatch) {
|
|
49
|
+
const fresh = new RegExp(re.source, re.flags);
|
|
50
|
+
for (const m of text.matchAll(fresh))
|
|
51
|
+
onMatch(m[0], m.index ?? 0);
|
|
52
|
+
}
|
|
53
|
+
// ── date (Safe Harbor: dates except year — DOB/admit/discharge/death) ────────
|
|
54
|
+
// ISO YYYY-MM-DD, US M/D/YYYY (and M/D/YY), and month-name forms. Many formats;
|
|
55
|
+
// per-result cap applies. Conservative: a bare 4-digit year alone is NOT a date
|
|
56
|
+
// (Safe Harbor exempts the year), so the year-only shape is deliberately unmatched.
|
|
57
|
+
const MONTHS = "jan(?:uary)?|feb(?:ruary)?|mar(?:ch)?|apr(?:il)?|may|jun(?:e)?|jul(?:y)?|aug(?:ust)?|sep(?:t(?:ember)?)?|oct(?:ober)?|nov(?:ember)?|dec(?:ember)?";
|
|
58
|
+
const DATE_ISO = /\b\d{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12]\d|3[01])\b/g;
|
|
59
|
+
const DATE_NUMERIC = /\b(?:0?[1-9]|1[0-2])[/-](?:0?[1-9]|[12]\d|3[01])[/-](?:\d{4}|\d{2})\b/g;
|
|
60
|
+
const DATE_MONTH_DMY = new RegExp(`\\b(?:0?[1-9]|[12]\\d|3[01])\\s+(?:${MONTHS})\\.?\\s+\\d{4}\\b`, "gi");
|
|
61
|
+
const DATE_MONTH_MDY = new RegExp(`\\b(?:${MONTHS})\\.?\\s+(?:0?[1-9]|[12]\\d|3[01])(?:st|nd|rd|th)?,?\\s+\\d{4}\\b`, "gi");
|
|
62
|
+
function findDates(text) {
|
|
63
|
+
const spans = [];
|
|
64
|
+
for (const re of [DATE_ISO, DATE_NUMERIC, DATE_MONTH_DMY, DATE_MONTH_MDY]) {
|
|
65
|
+
eachMatch(re, text, (v, i) => emit(spans, "pii:date", i, v.length));
|
|
66
|
+
}
|
|
67
|
+
return spans;
|
|
68
|
+
}
|
|
69
|
+
// ── age-over-89 (Safe Harbor: ages > 89 / dates indicating such age) ─────────
|
|
70
|
+
// A numeric RULE, not a regex-of-content (spec-sc2 §2): match an age-shaped
|
|
71
|
+
// phrase, then ACCEPT only when the number is 90..130 (a sane human-age bound —
|
|
72
|
+
// above it the digits are almost certainly something else, e.g. a quantity).
|
|
73
|
+
const AGE_CONTEXT = /\b(?:age[ds]?|aged)\b[^.\n\d]{0,12}(\d{2,3})\b|\b(\d{2,3})[ -]?(?:years?[ -]old|y(?:rs?)?[ -]?old|yo)\b/gi;
|
|
74
|
+
function findAgeOver89(text) {
|
|
75
|
+
const spans = [];
|
|
76
|
+
const fresh = new RegExp(AGE_CONTEXT.source, AGE_CONTEXT.flags);
|
|
77
|
+
for (const m of text.matchAll(fresh)) {
|
|
78
|
+
const digits = m[1] ?? m[2];
|
|
79
|
+
if (digits === undefined)
|
|
80
|
+
continue;
|
|
81
|
+
const n = Number.parseInt(digits, 10);
|
|
82
|
+
if (n < 90 || n > 130)
|
|
83
|
+
continue; // Safe Harbor floor is >89; 130 caps a human age
|
|
84
|
+
emit(spans, "pii:age_over_89", m.index ?? 0, m[0].length);
|
|
85
|
+
}
|
|
86
|
+
return spans;
|
|
87
|
+
}
|
|
88
|
+
// ── fax (Safe Harbor: telephone / fax) — label-anchored phone shape ──────────
|
|
89
|
+
const FAX = /\bfax\b[^.\n]{0,8}(?:\+?\d{1,3}[ .-]?)?(?:\(\d{3}\)|\d{3})[ .-]\d{3}[ .-]\d{4}\b/gi;
|
|
90
|
+
function findFax(text) {
|
|
91
|
+
const spans = [];
|
|
92
|
+
eachMatch(FAX, text, (v, i) => emit(spans, "pii:fax", i, v.length));
|
|
93
|
+
return spans;
|
|
94
|
+
}
|
|
95
|
+
// ── url (Safe Harbor: URLs; also the INJ-6 egress channel) ───────────────────
|
|
96
|
+
const URL_RE = /\bhttps?:\/\/[^\s"'<>)\]\\]+/gi;
|
|
97
|
+
function findUrls(text) {
|
|
98
|
+
const spans = [];
|
|
99
|
+
eachMatch(URL_RE, text, (v, i) => {
|
|
100
|
+
// Trim trailing sentence punctuation from the span length (the URL proper).
|
|
101
|
+
const trimmed = v.replace(/[.,;:]+$/, "");
|
|
102
|
+
emit(spans, "pii:url", i, trimmed.length);
|
|
103
|
+
});
|
|
104
|
+
return spans;
|
|
105
|
+
}
|
|
106
|
+
// ── ip (Safe Harbor: IP addresses) — v4 (octet-validated) + v6 ───────────────
|
|
107
|
+
const IPV4 = /\b(?:(?:25[0-5]|2[0-4]\d|1?\d?\d)\.){3}(?:25[0-5]|2[0-4]\d|1?\d?\d)\b/g;
|
|
108
|
+
const IPV6 = /\b(?:[0-9A-Fa-f]{1,4}:){2,7}[0-9A-Fa-f]{1,4}\b|\b(?:[0-9A-Fa-f]{1,4}:){1,7}:\b/g;
|
|
109
|
+
function findIps(text) {
|
|
110
|
+
const spans = [];
|
|
111
|
+
eachMatch(IPV4, text, (v, i) => emit(spans, "pii:ip", i, v.length));
|
|
112
|
+
eachMatch(IPV6, text, (v, i) => {
|
|
113
|
+
if (v.split(":").filter((p) => p !== "").length < 2)
|
|
114
|
+
return; // avoid a lone "a:" style false hit
|
|
115
|
+
emit(spans, "pii:ip", i, v.length);
|
|
116
|
+
});
|
|
117
|
+
return spans;
|
|
118
|
+
}
|
|
119
|
+
// ── zip (Safe Harbor: geographic < state) — conservative, anchored ───────────
|
|
120
|
+
// A bare 5-digit run floods (SSN-comment doctrine). Claimed only when it is
|
|
121
|
+
// distinctive: ZIP+4 (`12345-6789`), a `ST 12345` state+ZIP shape, or a labelled
|
|
122
|
+
// `ZIP: 12345`. Street/city need the sidecar and are NOT claimed here.
|
|
123
|
+
const ZIP_PLUS4 = /\b\d{5}-\d{4}\b/g;
|
|
124
|
+
const ZIP_STATE = /\b[A-Z]{2}\s+\d{5}(?:-\d{4})?\b/g;
|
|
125
|
+
const ZIP_LABELLED = /\bzip(?:\s*code)?\b[^.\n\d]{0,6}\d{5}(?:-\d{4})?\b/gi;
|
|
126
|
+
function findZips(text) {
|
|
127
|
+
const spans = [];
|
|
128
|
+
for (const re of [ZIP_PLUS4, ZIP_STATE, ZIP_LABELLED]) {
|
|
129
|
+
eachMatch(re, text, (v, i) => emit(spans, "pii:zip", i, v.length));
|
|
130
|
+
}
|
|
131
|
+
return spans;
|
|
132
|
+
}
|
|
133
|
+
// ── account-id (health-plan beneficiary #, account #, member #) ──────────────
|
|
134
|
+
// Label-anchored + shape — a bare id is unclaimable without a false-positive
|
|
135
|
+
// flood, so the label is what makes it real (the MRN doctrine).
|
|
136
|
+
const ACCOUNT_ID = /\b(?:account|acct|member|beneficiary|policy|plan|subscriber|group)\b[^.\n]{0,4}(?:id|no|number|#)?\s*[:#]?\s*[A-Za-z0-9][A-Za-z0-9-]{3,}\b/gi;
|
|
137
|
+
function findAccountIds(text) {
|
|
138
|
+
const spans = [];
|
|
139
|
+
eachMatch(ACCOUNT_ID, text, (v, i) => emit(spans, "pii:account_id", i, v.length));
|
|
140
|
+
return spans;
|
|
141
|
+
}
|
|
142
|
+
// ── license-id (certificate / license #) — label-anchored ────────────────────
|
|
143
|
+
const LICENSE_ID = /\b(?:licen[cs]e|licence|certificate|cert|permit|dl|driver'?s?\s+licen[cs]e)\b[^.\n]{0,4}(?:id|no|number|#)?\s*[:#]?\s*[A-Za-z0-9][A-Za-z0-9-]{3,}\b/gi;
|
|
144
|
+
function findLicenseIds(text) {
|
|
145
|
+
const spans = [];
|
|
146
|
+
eachMatch(LICENSE_ID, text, (v, i) => emit(spans, "pii:license_id", i, v.length));
|
|
147
|
+
return spans;
|
|
148
|
+
}
|
|
149
|
+
// ── vin (vehicle identifier) — 17-char VIN with check-digit validation ───────
|
|
150
|
+
const VIN_SHAPE = /\b[A-HJ-NPR-Z0-9]{17}\b/gi;
|
|
151
|
+
const VIN_TRANSLIT = {
|
|
152
|
+
A: 1, B: 2, C: 3, D: 4, E: 5, F: 6, G: 7, H: 8, J: 1, K: 2, L: 3, M: 4, N: 5,
|
|
153
|
+
P: 7, R: 9, S: 2, T: 3, U: 4, V: 5, W: 6, X: 7, Y: 8, Z: 9,
|
|
154
|
+
};
|
|
155
|
+
const VIN_WEIGHTS = [8, 7, 6, 5, 4, 3, 2, 10, 0, 9, 8, 7, 6, 5, 4, 3, 2];
|
|
156
|
+
/** VIN check-digit rule (position 9): weighted transliteration mod 11, where 10
|
|
157
|
+
* ⇒ 'X'. Separates a real VIN from any 17 alphanumerics — the difference between
|
|
158
|
+
* a false-positive flood and a claimable identifier. */
|
|
159
|
+
function vinValid(vin) {
|
|
160
|
+
const up = vin.toUpperCase();
|
|
161
|
+
if (up.length !== 17)
|
|
162
|
+
return false;
|
|
163
|
+
let sum = 0;
|
|
164
|
+
for (let i = 0; i < 17; i += 1) {
|
|
165
|
+
const ch = up[i];
|
|
166
|
+
const val = ch >= "0" && ch <= "9" ? ch.charCodeAt(0) - 48 : VIN_TRANSLIT[ch];
|
|
167
|
+
if (val === undefined)
|
|
168
|
+
return false; // I/O/Q or other invalid char
|
|
169
|
+
sum += val * VIN_WEIGHTS[i];
|
|
170
|
+
}
|
|
171
|
+
const check = sum % 11;
|
|
172
|
+
const expected = check === 10 ? "X" : String(check);
|
|
173
|
+
return up[8] === expected;
|
|
174
|
+
}
|
|
175
|
+
function findVins(text) {
|
|
176
|
+
const spans = [];
|
|
177
|
+
eachMatch(VIN_SHAPE, text, (v, i) => {
|
|
178
|
+
if (!vinValid(v))
|
|
179
|
+
return;
|
|
180
|
+
emit(spans, "pii:vin", i, v.length);
|
|
181
|
+
});
|
|
182
|
+
return spans;
|
|
183
|
+
}
|
|
184
|
+
// ── device-id (device / serial identifiers) — MAC, IMEI, label-anchored ──────
|
|
185
|
+
const MAC = /\b(?:[0-9A-Fa-f]{2}:){5}[0-9A-Fa-f]{2}\b/g;
|
|
186
|
+
const IMEI_LABELLED = /\bimei\b[^.\n\d]{0,6}(\d{15})\b/gi;
|
|
187
|
+
const DEVICE_LABELLED = /\b(?:device|serial|udid|s\/n|sn)\b[^.\n]{0,4}(?:id|no|number|#)?\s*[:#]?\s*[A-Za-z0-9][A-Za-z0-9-]{3,}\b/gi;
|
|
188
|
+
function findDeviceIds(text) {
|
|
189
|
+
const spans = [];
|
|
190
|
+
eachMatch(MAC, text, (v, i) => emit(spans, "pii:device_id", i, v.length));
|
|
191
|
+
const fresh = new RegExp(IMEI_LABELLED.source, IMEI_LABELLED.flags);
|
|
192
|
+
for (const m of text.matchAll(fresh)) {
|
|
193
|
+
const digits = m[1];
|
|
194
|
+
if (digits === undefined || !(0, scrub_1.luhnValid)(digits))
|
|
195
|
+
continue; // IMEI is Luhn-valid
|
|
196
|
+
emit(spans, "pii:device_id", m.index ?? 0, m[0].length);
|
|
197
|
+
}
|
|
198
|
+
eachMatch(DEVICE_LABELLED, text, (v, i) => emit(spans, "pii:device_id", i, v.length));
|
|
199
|
+
return spans;
|
|
200
|
+
}
|
|
201
|
+
/** The SC-2 deterministic rule set (spec-sc2 §2). One rule per Safe Harbor class
|
|
202
|
+
* that has a deterministic shape; names/streets/biometrics are NOT here (they
|
|
203
|
+
* are `sidecar`/`out-of-scope` in the coverage table). */
|
|
204
|
+
const RULES = [
|
|
205
|
+
{ type: "pii:date", id: "pii:date@v1", find: findDates },
|
|
206
|
+
{ type: "pii:age_over_89", id: "pii:age_over_89@v1", find: findAgeOver89 },
|
|
207
|
+
{ type: "pii:fax", id: "pii:fax@v1", find: findFax },
|
|
208
|
+
{ type: "pii:url", id: "pii:url@v1", find: findUrls },
|
|
209
|
+
{ type: "pii:ip", id: "pii:ip@v1", find: findIps },
|
|
210
|
+
{ type: "pii:zip", id: "pii:zip@v1", find: findZips },
|
|
211
|
+
{ type: "pii:account_id", id: "pii:account_id@v1", find: findAccountIds },
|
|
212
|
+
{ type: "pii:license_id", id: "pii:license_id@v1", find: findLicenseIds },
|
|
213
|
+
{ type: "pii:vin", id: "pii:vin@v1", find: findVins },
|
|
214
|
+
{ type: "pii:device_id", id: "pii:device_id@v1", find: findDeviceIds },
|
|
215
|
+
];
|
|
216
|
+
/** The registry id of the convenience PACK — configuring it in a route's
|
|
217
|
+
* `screen.detectors` opts in to ALL ten deterministic Safe Harbor detectors at
|
|
218
|
+
* once. Individual `pii:<slug>@v1` ids opt in to just that one. */
|
|
219
|
+
exports.SAFE_HARBOR_PACK_ID = "safe-harbor@v1";
|
|
220
|
+
/** All individual Safe Harbor detector ids, for policy validation. */
|
|
221
|
+
exports.SAFE_HARBOR_IDS = new Set(RULES.map((r) => r.id));
|
|
222
|
+
/** True when `id` names a Safe Harbor detector (a `pii:<slug>@v1` or the pack).
|
|
223
|
+
* The screen policy validator uses this to accept the id at load time. */
|
|
224
|
+
function isSafeHarborId(id) {
|
|
225
|
+
return id === exports.SAFE_HARBOR_PACK_ID || exports.SAFE_HARBOR_IDS.has(id);
|
|
226
|
+
}
|
|
227
|
+
/** Collapse overlapping spans of one detector to a single span so one underlying
|
|
228
|
+
* identifier matched by two sub-patterns (e.g. a ZIP caught by both the ZIP+4 and
|
|
229
|
+
* the state+ZIP rule) COUNTS ONCE. Sorted by start; a span whose range overlaps a
|
|
230
|
+
* kept span is dropped (conservative — an adjacency undercount is cheaper than a
|
|
231
|
+
* double count). Offsets only, never a value. */
|
|
232
|
+
function dedupeOverlaps(spans) {
|
|
233
|
+
const sorted = [...spans].sort((a, b) => a.start - b.start || b.end - a.end);
|
|
234
|
+
const kept = [];
|
|
235
|
+
let lastEnd = -1;
|
|
236
|
+
for (const s of sorted) {
|
|
237
|
+
if (s.start >= lastEnd) {
|
|
238
|
+
kept.push(s);
|
|
239
|
+
lastEnd = s.end;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
return kept;
|
|
243
|
+
}
|
|
244
|
+
/** Wrap one rule as the shared `Detector` (kind deterministic, confidence 1). */
|
|
245
|
+
function detectorFor(rule) {
|
|
246
|
+
return {
|
|
247
|
+
id: rule.id,
|
|
248
|
+
kind: "deterministic",
|
|
249
|
+
detect: (input) => Promise.resolve(dedupeOverlaps(rule.find(input.text))),
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
/** Every Safe Harbor detector (one per type), for the pack. */
|
|
253
|
+
function safeHarborDetectors() {
|
|
254
|
+
return RULES.map(detectorFor);
|
|
255
|
+
}
|
|
256
|
+
/** The Safe Harbor detector for one id, or `undefined` if `id` is not one.
|
|
257
|
+
* `SAFE_HARBOR_PACK_ID` returns `undefined` here — the pack expands to
|
|
258
|
+
* {@link safeHarborDetectors}; a caller resolves the pack separately. */
|
|
259
|
+
function safeHarborDetectorById(id) {
|
|
260
|
+
const rule = RULES.find((r) => r.id === id);
|
|
261
|
+
return rule === undefined ? undefined : detectorFor(rule);
|
|
262
|
+
}
|
|
263
|
+
/** The detector identities (id + version) for a configured id — the pack
|
|
264
|
+
* expands to all ten; a single id resolves to one. Used to populate the
|
|
265
|
+
* receipt's `detectors[]` at resolve time (counts-only, never a value). */
|
|
266
|
+
function safeHarborIdentities(id) {
|
|
267
|
+
if (id === exports.SAFE_HARBOR_PACK_ID)
|
|
268
|
+
return RULES.map((r) => ({ id: r.id, version: "v1" }));
|
|
269
|
+
return exports.SAFE_HARBOR_IDS.has(id) ? [{ id, version: "v1" }] : [];
|
|
270
|
+
}
|
|
271
|
+
/** Build the Detector instances a configured id contributes (pack ⇒ all ten,
|
|
272
|
+
* single id ⇒ one, unknown ⇒ none). */
|
|
273
|
+
function safeHarborDetectorsFor(id) {
|
|
274
|
+
if (id === exports.SAFE_HARBOR_PACK_ID)
|
|
275
|
+
return safeHarborDetectors();
|
|
276
|
+
const one = safeHarborDetectorById(id);
|
|
277
|
+
return one === undefined ? [] : [one];
|
|
278
|
+
}
|
|
@@ -7,12 +7,12 @@
|
|
|
7
7
|
* rung 0 — implicit signals only: conformance / repair / refusal rates
|
|
8
8
|
* from telemetry. Enough confidence for schema-mechanical swap
|
|
9
9
|
* proposals (the bake-off gate).
|
|
10
|
-
* rung 1 — ≥
|
|
10
|
+
* rung 1 — ≥ RUNG1_MIN_GRADES grades attached: prose
|
|
11
11
|
* routes (no schema to conform to) gain proposal confidence.
|
|
12
12
|
* rung 2+ — judges; Phase 5+, out of scope by decision.
|
|
13
13
|
*/
|
|
14
|
-
import type {
|
|
15
|
-
export declare const
|
|
14
|
+
import type { GradeRow, TelemetryRow } from "../types/telemetry";
|
|
15
|
+
export declare const RUNG1_MIN_GRADES = 10;
|
|
16
16
|
export interface RouteCoverage {
|
|
17
17
|
readonly route: string;
|
|
18
18
|
readonly samples: number;
|
|
@@ -20,13 +20,16 @@ export interface RouteCoverage {
|
|
|
20
20
|
readonly conformRate: number;
|
|
21
21
|
readonly repairRate: number;
|
|
22
22
|
readonly refusalRate: number;
|
|
23
|
-
readonly
|
|
23
|
+
readonly gradeCount: number;
|
|
24
24
|
readonly rung: 0 | 1;
|
|
25
25
|
/** Teaching copy: what reaching the next rung takes and unlocks. */
|
|
26
26
|
readonly nextRungUnlock: string;
|
|
27
27
|
}
|
|
28
|
-
/** Attribution: a
|
|
29
|
-
*
|
|
30
|
-
* to nothing (never guessed).
|
|
31
|
-
|
|
28
|
+
/** Attribution: a grade joins a route via its inference-subject id, or via its
|
|
29
|
+
* run-subject (episode) id matching a row's run_id tag. Unmatched grades attach
|
|
30
|
+
* to nothing (never guessed). Grade primitive (R6): every grade counts toward
|
|
31
|
+
* readiness — a wrapper-written feedback IS now a grade, so this is
|
|
32
|
+
* behaviour-preserving for the Rung-1 threshold. Artifact-subject grades never
|
|
33
|
+
* resolve to a route here (no artifact→route join) and simply do not count. */
|
|
34
|
+
export declare function computeCoverage(rows: readonly TelemetryRow[], grades: readonly GradeRow[]): RouteCoverage[];
|
|
32
35
|
//# sourceMappingURL=coverage.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"coverage.d.ts","sourceRoot":"","sources":["../../src/feedback/coverage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"coverage.d.ts","sourceRoot":"","sources":["../../src/feedback/coverage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEjE,eAAO,MAAM,gBAAgB,KAAK,CAAC;AAEnC,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,6EAA6E;IAC7E,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC;IACrB,oEAAoE;IACpE,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;CACjC;AAED;;;;;+EAK+E;AAC/E,wBAAgB,eAAe,CAC7B,IAAI,EAAE,SAAS,YAAY,EAAE,EAC7B,MAAM,EAAE,SAAS,QAAQ,EAAE,GAC1B,aAAa,EAAE,CAqFjB"}
|
|
@@ -8,18 +8,21 @@
|
|
|
8
8
|
* rung 0 — implicit signals only: conformance / repair / refusal rates
|
|
9
9
|
* from telemetry. Enough confidence for schema-mechanical swap
|
|
10
10
|
* proposals (the bake-off gate).
|
|
11
|
-
* rung 1 — ≥
|
|
11
|
+
* rung 1 — ≥ RUNG1_MIN_GRADES grades attached: prose
|
|
12
12
|
* routes (no schema to conform to) gain proposal confidence.
|
|
13
13
|
* rung 2+ — judges; Phase 5+, out of scope by decision.
|
|
14
14
|
*/
|
|
15
15
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
-
exports.
|
|
16
|
+
exports.RUNG1_MIN_GRADES = void 0;
|
|
17
17
|
exports.computeCoverage = computeCoverage;
|
|
18
|
-
exports.
|
|
19
|
-
/** Attribution: a
|
|
20
|
-
*
|
|
21
|
-
* to nothing (never guessed).
|
|
22
|
-
|
|
18
|
+
exports.RUNG1_MIN_GRADES = 10;
|
|
19
|
+
/** Attribution: a grade joins a route via its inference-subject id, or via its
|
|
20
|
+
* run-subject (episode) id matching a row's run_id tag. Unmatched grades attach
|
|
21
|
+
* to nothing (never guessed). Grade primitive (R6): every grade counts toward
|
|
22
|
+
* readiness — a wrapper-written feedback IS now a grade, so this is
|
|
23
|
+
* behaviour-preserving for the Rung-1 threshold. Artifact-subject grades never
|
|
24
|
+
* resolve to a route here (no artifact→route join) and simply do not count. */
|
|
25
|
+
function computeCoverage(rows, grades) {
|
|
23
26
|
const routeByInferenceId = new Map();
|
|
24
27
|
const routeByEpisode = new Map();
|
|
25
28
|
const byRoute = new Map();
|
|
@@ -42,7 +45,7 @@ function computeCoverage(rows, feedback) {
|
|
|
42
45
|
conform: 0,
|
|
43
46
|
repaired: 0,
|
|
44
47
|
refused: 0,
|
|
45
|
-
|
|
48
|
+
grades: 0,
|
|
46
49
|
};
|
|
47
50
|
agg.samples += 1;
|
|
48
51
|
if (row.failureClass === null)
|
|
@@ -63,22 +66,32 @@ function computeCoverage(rows, feedback) {
|
|
|
63
66
|
// Unparseable tags never break coverage — the row still counts above.
|
|
64
67
|
}
|
|
65
68
|
}
|
|
66
|
-
for (const
|
|
67
|
-
|
|
68
|
-
|
|
69
|
+
for (const g of grades) {
|
|
70
|
+
// R6 (grade primitive): EVERY grade counts toward Rung 1, not just the
|
|
71
|
+
// wrapper-written thumbs the pre-grade `feedback` table held. A grade counts
|
|
72
|
+
// only when its subject resolves to a route: an inference-subject id, or a
|
|
73
|
+
// run-subject (episode) id matching a row's run_id tag. Artifact-subject
|
|
74
|
+
// grades and native run verdicts (whose run-subject id is a run UUID, not an
|
|
75
|
+
// episode key) never resolve to a route here, so they do not over-count —
|
|
76
|
+
// behaviour-preserving for existing corpora while opening Rung 1 to
|
|
77
|
+
// model-judge/agent grades on inferences (the R6 intent).
|
|
78
|
+
const inferenceId = g.subjectKind === "inference" ? g.subjectId : null;
|
|
79
|
+
const episodeKey = g.subjectKind === "run" ? g.subjectId : null;
|
|
80
|
+
const route = (inferenceId !== null ? routeByInferenceId.get(inferenceId) : undefined) ??
|
|
81
|
+
(episodeKey !== null ? routeByEpisode.get(episodeKey) : undefined);
|
|
69
82
|
if (route === undefined)
|
|
70
83
|
continue;
|
|
71
84
|
const agg = byRoute.get(route);
|
|
72
85
|
if (agg !== undefined)
|
|
73
|
-
agg.
|
|
86
|
+
agg.grades += 1;
|
|
74
87
|
}
|
|
75
88
|
return [...byRoute.entries()]
|
|
76
89
|
.sort(([a], [b]) => a.localeCompare(b))
|
|
77
90
|
.map(([route, agg]) => {
|
|
78
|
-
const rung = agg.
|
|
91
|
+
const rung = agg.grades >= exports.RUNG1_MIN_GRADES ? 1 : 0;
|
|
79
92
|
const nextRungUnlock = rung === 0
|
|
80
|
-
? `Attach ${exports.
|
|
81
|
-
`(${agg.
|
|
93
|
+
? `Attach ${exports.RUNG1_MIN_GRADES - agg.grades} more rig.grade() grades ` +
|
|
94
|
+
`(${agg.grades}/${exports.RUNG1_MIN_GRADES}) to reach rung 1 — judged confidence ` +
|
|
82
95
|
"for routes without a schema to conform to."
|
|
83
96
|
: "Rung 2 (LLM judges — value accuracy beyond mechanical conformance) arrives in Phase 5.";
|
|
84
97
|
return {
|
|
@@ -87,7 +100,7 @@ function computeCoverage(rows, feedback) {
|
|
|
87
100
|
conformRate: agg.samples === 0 ? 0 : agg.conform / agg.samples,
|
|
88
101
|
repairRate: agg.samples === 0 ? 0 : agg.repaired / agg.samples,
|
|
89
102
|
refusalRate: agg.samples === 0 ? 0 : agg.refused / agg.samples,
|
|
90
|
-
|
|
103
|
+
gradeCount: agg.grades,
|
|
91
104
|
rung,
|
|
92
105
|
nextRungUnlock,
|
|
93
106
|
};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* rig.grade() — the unified judgment primitive (grade primitive, R1).
|
|
3
|
+
*
|
|
4
|
+
* A grade attaches a judgment to a SUBJECT (an inference / run / artifact):
|
|
5
|
+
* `{ score: 0–1 (primitive), scale?, comment?, kind, grader?, source? }`. The
|
|
6
|
+
* pass/fail VERDICT is DERIVED at read time (`pass = score >= threshold`), never
|
|
7
|
+
* stored. `rig.grade` writes one local `grades` row (synchronous SQLite insert,
|
|
8
|
+
* fire-and-forget); the exporter mirrors it to the cloud.
|
|
9
|
+
*
|
|
10
|
+
* `rig.grade` is the SOLE judgment write API. The temporary GP-1 compat wrappers
|
|
11
|
+
* (`rig.feedback` / `artifact.evaluate` / `run.evaluate`) and their adapters were
|
|
12
|
+
* removed in GP-3 — every judgment now builds a grade directly.
|
|
13
|
+
*/
|
|
14
|
+
import type { GradeRow, GradeSubject } from "../types/telemetry";
|
|
15
|
+
/** Options for `rig.grade(subject, opts)`. `score` is the 0–1 primitive and is
|
|
16
|
+
* required; everything else is optional display / provenance. */
|
|
17
|
+
export interface GradeOpts {
|
|
18
|
+
/** 0–1 primitive (always present). up/pass = 1.0, down/fail = 0.0, else graded. */
|
|
19
|
+
readonly score: number;
|
|
20
|
+
/** Optional DISPLAY scale — `{ max }` (e.g. out of 100) or `{ label }` (e.g. "B+").
|
|
21
|
+
* Never changes the derived verdict, which is a threshold on `score`. */
|
|
22
|
+
readonly scale?: {
|
|
23
|
+
readonly max: number;
|
|
24
|
+
} | {
|
|
25
|
+
readonly label: string;
|
|
26
|
+
};
|
|
27
|
+
/** Written guidance saved for a later improvement path (was note/explanation). */
|
|
28
|
+
readonly comment?: string;
|
|
29
|
+
readonly kind: "human" | "model-judge" | "deterministic";
|
|
30
|
+
/** Optional specific grader name (e.g. "gpt-5-judge", "schema-check"). */
|
|
31
|
+
readonly grader?: string;
|
|
32
|
+
/** Provenance (e.g. "sdk", "console", a review-agent name). */
|
|
33
|
+
readonly source?: string;
|
|
34
|
+
/** The grade's own org — server-supplied ONLY, already authorized (T3). Omit
|
|
35
|
+
* from application code (a rig has one org and the exporter knows it). */
|
|
36
|
+
readonly orgId?: string;
|
|
37
|
+
/** Authenticated user who recorded it — same provenance rule as `orgId`. */
|
|
38
|
+
readonly createdBy?: string | null;
|
|
39
|
+
}
|
|
40
|
+
/** Build a GradeRow from a subject + opts. Validates the score bound (the one
|
|
41
|
+
* primitive — a judgment with no numeric score has no place in the grade model). */
|
|
42
|
+
export declare function buildGradeRow(subject: GradeSubject, opts: GradeOpts): GradeRow;
|
|
43
|
+
/** Build the rig's `grade` surface over a grade writer (the telemetry store).
|
|
44
|
+
* Kept here (not inlined in index.ts) so the SDK entrypoint stays under the LOC
|
|
45
|
+
* cap and the grade write surface lives with the primitive. */
|
|
46
|
+
export declare function makeGradeApi(store: {
|
|
47
|
+
recordGrade(row: GradeRow): void;
|
|
48
|
+
}): {
|
|
49
|
+
grade(subject: GradeSubject, opts: GradeOpts): GradeRow;
|
|
50
|
+
};
|
|
51
|
+
//# sourceMappingURL=grade.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"grade.d.ts","sourceRoot":"","sources":["../../src/feedback/grade.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEjE;iEACiE;AACjE,MAAM,WAAW,SAAS;IACxB,mFAAmF;IACnF,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB;6EACyE;IACzE,QAAQ,CAAC,KAAK,CAAC,EAAE;QAAE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;KAAE,GAAG;QAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IACvE,kFAAkF;IAClF,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,OAAO,GAAG,aAAa,GAAG,eAAe,CAAC;IACzD,0EAA0E;IAC1E,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,+DAA+D;IAC/D,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB;8EAC0E;IAC1E,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,4EAA4E;IAC5E,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACpC;AAQD;oFACoF;AACpF,wBAAgB,aAAa,CAAC,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,SAAS,GAAG,QAAQ,CAuB9E;AAED;;+DAE+D;AAC/D,wBAAgB,YAAY,CAAC,KAAK,EAAE;IAAE,WAAW,CAAC,GAAG,EAAE,QAAQ,GAAG,IAAI,CAAA;CAAE,GAAG;IACzE,KAAK,CAAC,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,SAAS,GAAG,QAAQ,CAAC;CACzD,CAQA"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* rig.grade() — the unified judgment primitive (grade primitive, R1).
|
|
4
|
+
*
|
|
5
|
+
* A grade attaches a judgment to a SUBJECT (an inference / run / artifact):
|
|
6
|
+
* `{ score: 0–1 (primitive), scale?, comment?, kind, grader?, source? }`. The
|
|
7
|
+
* pass/fail VERDICT is DERIVED at read time (`pass = score >= threshold`), never
|
|
8
|
+
* stored. `rig.grade` writes one local `grades` row (synchronous SQLite insert,
|
|
9
|
+
* fire-and-forget); the exporter mirrors it to the cloud.
|
|
10
|
+
*
|
|
11
|
+
* `rig.grade` is the SOLE judgment write API. The temporary GP-1 compat wrappers
|
|
12
|
+
* (`rig.feedback` / `artifact.evaluate` / `run.evaluate`) and their adapters were
|
|
13
|
+
* removed in GP-3 — every judgment now builds a grade directly.
|
|
14
|
+
*/
|
|
15
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
+
exports.buildGradeRow = buildGradeRow;
|
|
17
|
+
exports.makeGradeApi = makeGradeApi;
|
|
18
|
+
const node_crypto_1 = require("node:crypto");
|
|
19
|
+
function scaleFields(scale) {
|
|
20
|
+
if (scale === undefined)
|
|
21
|
+
return { scaleMax: null, scaleLabel: null };
|
|
22
|
+
if ("max" in scale)
|
|
23
|
+
return { scaleMax: scale.max, scaleLabel: null };
|
|
24
|
+
return { scaleMax: null, scaleLabel: scale.label };
|
|
25
|
+
}
|
|
26
|
+
/** Build a GradeRow from a subject + opts. Validates the score bound (the one
|
|
27
|
+
* primitive — a judgment with no numeric score has no place in the grade model). */
|
|
28
|
+
function buildGradeRow(subject, opts) {
|
|
29
|
+
if (subject.id === "") {
|
|
30
|
+
throw new Error("grade subject must have a non-empty id");
|
|
31
|
+
}
|
|
32
|
+
if (!Number.isFinite(opts.score) || opts.score < 0 || opts.score > 1) {
|
|
33
|
+
throw new Error(`grade score must be in [0, 1], got ${opts.score}`);
|
|
34
|
+
}
|
|
35
|
+
const { scaleMax, scaleLabel } = scaleFields(opts.scale);
|
|
36
|
+
return {
|
|
37
|
+
id: (0, node_crypto_1.randomUUID)(),
|
|
38
|
+
subjectKind: subject.kind,
|
|
39
|
+
subjectId: subject.id,
|
|
40
|
+
score: opts.score,
|
|
41
|
+
scaleMax,
|
|
42
|
+
scaleLabel,
|
|
43
|
+
comment: opts.comment ?? null,
|
|
44
|
+
kind: opts.kind,
|
|
45
|
+
grader: opts.grader ?? null,
|
|
46
|
+
source: opts.source ?? null,
|
|
47
|
+
orgId: opts.orgId !== undefined && opts.orgId !== "" ? opts.orgId : null,
|
|
48
|
+
createdBy: opts.createdBy ?? null,
|
|
49
|
+
ts: new Date().toISOString(),
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
/** Build the rig's `grade` surface over a grade writer (the telemetry store).
|
|
53
|
+
* Kept here (not inlined in index.ts) so the SDK entrypoint stays under the LOC
|
|
54
|
+
* cap and the grade write surface lives with the primitive. */
|
|
55
|
+
function makeGradeApi(store) {
|
|
56
|
+
return {
|
|
57
|
+
grade(subject, opts) {
|
|
58
|
+
const row = buildGradeRow(subject, opts);
|
|
59
|
+
store.recordGrade(row);
|
|
60
|
+
return row;
|
|
61
|
+
},
|
|
62
|
+
};
|
|
63
|
+
}
|
|
@@ -42,7 +42,7 @@ export declare const MODELRIG_HEADERS: {
|
|
|
42
42
|
/** "provider/model" that repaired the output, when repair fired. */
|
|
43
43
|
readonly repairedBy: "x-modelrig-repaired-by";
|
|
44
44
|
readonly costUsd: "x-modelrig-cost-usd";
|
|
45
|
-
/** The `rig.
|
|
45
|
+
/** The `rig.grade()` inference handle (telemetry inference id). */
|
|
46
46
|
readonly inferenceId: "x-modelrig-inference-id";
|
|
47
47
|
};
|
|
48
48
|
export declare const MODELRIG_REQUEST_HEADERS: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http-protocol.d.ts","sourceRoot":"","sources":["../../src/gateway/http-protocol.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAGH,OAAO,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAE9E,uCAAuC;AACvC,eAAO,MAAM,qBAAqB,yBAAyB,CAAC;AAC5D,2EAA2E;AAC3E,eAAO,MAAM,WAAW,eAAe,CAAC;AAExC,6DAA6D;AAC7D,eAAO,MAAM,wBAAwB,IAAI,CAAC;AAO1C,eAAO,MAAM,gBAAgB;IAC3B,0EAA0E;;IAE1E;;;;eAIW;;;;IAIX,yEAAyE;;IAEzE,oEAAoE;;;IAGpE,
|
|
1
|
+
{"version":3,"file":"http-protocol.d.ts","sourceRoot":"","sources":["../../src/gateway/http-protocol.ts"],"names":[],"mappings":"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"}
|
|
@@ -51,7 +51,7 @@ exports.MODELRIG_HEADERS = {
|
|
|
51
51
|
/** "provider/model" that repaired the output, when repair fired. */
|
|
52
52
|
repairedBy: "x-modelrig-repaired-by",
|
|
53
53
|
costUsd: "x-modelrig-cost-usd",
|
|
54
|
-
/** The `rig.
|
|
54
|
+
/** The `rig.grade()` inference handle (telemetry inference id). */
|
|
55
55
|
inferenceId: "x-modelrig-inference-id",
|
|
56
56
|
};
|
|
57
57
|
// Request-side extension headers (spec §3.4).
|