modelrig 0.8.1 → 0.10.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 +324 -0
- package/README.md +55 -29
- package/data/PROVENANCE.md +14 -0
- package/data/pricing-map.json +26 -0
- package/dist/adapters/attempt-meta-map.d.ts +8 -1
- package/dist/adapters/attempt-meta-map.d.ts.map +1 -1
- package/dist/adapters/attempt-meta-map.js +4 -0
- package/dist/adapters/build-adapters.js +2 -2
- package/dist/adapters/gemini.d.ts +28 -1
- package/dist/adapters/gemini.d.ts.map +1 -1
- package/dist/adapters/gemini.js +38 -9
- package/dist/adapters/grok.d.ts.map +1 -1
- package/dist/adapters/grok.js +53 -4
- package/dist/adapters/openai-compat.d.ts +8 -2
- package/dist/adapters/openai-compat.d.ts.map +1 -1
- package/dist/adapters/openai-compat.js +8 -1
- package/dist/adapters/openai-stream.d.ts +10 -2
- package/dist/adapters/openai-stream.d.ts.map +1 -1
- package/dist/adapters/openai-stream.js +5 -1
- package/dist/adapters/openai.d.ts +10 -1
- package/dist/adapters/openai.d.ts.map +1 -1
- package/dist/adapters/openai.js +57 -7
- package/dist/adapters/responses-api.d.ts +61 -0
- package/dist/adapters/responses-api.d.ts.map +1 -0
- package/dist/adapters/responses-api.js +124 -0
- package/dist/artifacts/artifact.d.ts +31 -12
- package/dist/artifacts/artifact.d.ts.map +1 -1
- package/dist/artifacts/artifact.js +218 -188
- package/dist/artifacts/index.d.ts +15 -5
- package/dist/artifacts/index.d.ts.map +1 -1
- package/dist/artifacts/index.js +19 -5
- 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/groundedness.d.ts +58 -0
- package/dist/bakeoff/groundedness.d.ts.map +1 -0
- package/dist/bakeoff/groundedness.js +165 -0
- package/dist/bakeoff/quality.d.ts +43 -0
- package/dist/bakeoff/quality.d.ts.map +1 -1
- package/dist/bakeoff/quality.js +31 -0
- package/dist/bakeoff/replay.d.ts +11 -0
- package/dist/bakeoff/replay.d.ts.map +1 -1
- package/dist/bakeoff/replay.js +12 -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 +22 -42
- package/dist/config.d.ts +85 -29
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +109 -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/doctor-cli.d.ts +7 -0
- package/dist/doctor-cli.d.ts.map +1 -0
- package/dist/doctor-cli.js +67 -0
- package/dist/doctor-preflight.d.ts +52 -0
- package/dist/doctor-preflight.d.ts.map +1 -0
- package/dist/doctor-preflight.js +112 -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 +58 -0
- package/dist/feedback/grade.d.ts.map +1 -0
- package/dist/feedback/grade.js +67 -0
- package/dist/gateway/http-protocol.d.ts +20 -1
- package/dist/gateway/http-protocol.d.ts.map +1 -1
- package/dist/gateway/http-protocol.js +1 -1
- package/dist/gateway/serve-client.d.ts +99 -0
- package/dist/gateway/serve-client.d.ts.map +1 -0
- package/dist/gateway/serve-client.js +360 -0
- package/dist/index.d.ts +68 -29
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +167 -46
- 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/prompts/manifest.d.ts +128 -0
- package/dist/prompts/manifest.d.ts.map +1 -0
- package/dist/prompts/manifest.js +214 -0
- package/dist/prompts/prompt-fetch.d.ts +84 -0
- package/dist/prompts/prompt-fetch.d.ts.map +1 -0
- package/dist/prompts/prompt-fetch.js +120 -0
- package/dist/prompts/prompt-resolve.d.ts +76 -0
- package/dist/prompts/prompt-resolve.d.ts.map +1 -0
- package/dist/prompts/prompt-resolve.js +93 -0
- package/dist/prompts/slot-resolver.d.ts +91 -0
- package/dist/prompts/slot-resolver.d.ts.map +1 -0
- package/dist/prompts/slot-resolver.js +135 -0
- package/dist/prompts/tools-register.d.ts +60 -0
- package/dist/prompts/tools-register.d.ts.map +1 -0
- package/dist/prompts/tools-register.js +48 -0
- package/dist/prompts/version-hash.d.ts +29 -0
- package/dist/prompts/version-hash.d.ts.map +1 -0
- package/dist/prompts/version-hash.js +54 -0
- package/dist/prompts-export-cli.d.ts +21 -0
- package/dist/prompts-export-cli.d.ts.map +1 -0
- package/dist/prompts-export-cli.js +130 -0
- 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/cache-policy.d.ts.map +1 -1
- package/dist/registry/cache-policy.js +22 -0
- package/dist/registry/pricing-shape.d.ts +67 -8
- package/dist/registry/pricing-shape.d.ts.map +1 -1
- package/dist/registry/pricing-shape.js +50 -13
- package/dist/registry/pricing.d.ts +6 -5
- package/dist/registry/pricing.d.ts.map +1 -1
- package/dist/registry/pricing.js +9 -5
- 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/destination-loader.d.ts +16 -0
- package/dist/routes/destination-loader.d.ts.map +1 -0
- package/dist/routes/destination-loader.js +29 -0
- package/dist/routes/draft.d.ts +7 -0
- package/dist/routes/draft.d.ts.map +1 -1
- package/dist/routes/draft.js +12 -0
- package/dist/routes/loader.d.ts.map +1 -1
- package/dist/routes/loader.js +31 -56
- 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/output-loader.d.ts +42 -0
- package/dist/routes/output-loader.d.ts.map +1 -0
- package/dist/routes/output-loader.js +112 -0
- package/dist/routes/prompt-loader.d.ts +49 -0
- package/dist/routes/prompt-loader.d.ts.map +1 -0
- package/dist/routes/prompt-loader.js +113 -0
- package/dist/routes/resolved-bundle.d.ts +69 -0
- package/dist/routes/resolved-bundle.d.ts.map +1 -1
- package/dist/routes/resolved-bundle.js +76 -0
- package/dist/routes/screen-loader.d.ts +29 -1
- package/dist/routes/screen-loader.d.ts.map +1 -1
- package/dist/routes/screen-loader.js +59 -1
- package/dist/run/accept.d.ts +5 -0
- package/dist/run/accept.d.ts.map +1 -1
- package/dist/run/accept.js +2 -0
- package/dist/run/cost.d.ts +31 -2
- package/dist/run/cost.d.ts.map +1 -1
- package/dist/run/cost.js +57 -2
- package/dist/run/destination.d.ts +39 -0
- package/dist/run/destination.d.ts.map +1 -0
- package/dist/run/destination.js +45 -0
- package/dist/run/dispatch.d.ts +67 -16
- package/dist/run/dispatch.d.ts.map +1 -1
- package/dist/run/dispatch.js +133 -29
- 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/raw-defaults.d.ts.map +1 -1
- package/dist/run/raw-defaults.js +6 -1
- package/dist/run/raw-finalize.d.ts +50 -0
- package/dist/run/raw-finalize.d.ts.map +1 -0
- package/dist/run/raw-finalize.js +266 -0
- package/dist/run/raw-knobs.d.ts +36 -0
- package/dist/run/raw-knobs.d.ts.map +1 -0
- package/dist/run/raw-knobs.js +99 -0
- package/dist/run/raw-request.d.ts +24 -0
- package/dist/run/raw-request.d.ts.map +1 -0
- package/dist/run/raw-request.js +69 -0
- package/dist/run/raw-schema.d.ts +76 -0
- package/dist/run/raw-schema.d.ts.map +1 -0
- package/dist/run/raw-schema.js +166 -0
- package/dist/run/raw-search-cost.d.ts +48 -0
- package/dist/run/raw-search-cost.d.ts.map +1 -0
- package/dist/run/raw-search-cost.js +78 -0
- package/dist/run/raw-support.d.ts +64 -6
- package/dist/run/raw-support.d.ts.map +1 -1
- package/dist/run/raw-support.js +84 -11
- package/dist/run/raw.d.ts +25 -26
- package/dist/run/raw.d.ts.map +1 -1
- package/dist/run/raw.js +30 -351
- package/dist/run/record-attempt.d.ts +12 -0
- package/dist/run/record-attempt.d.ts.map +1 -1
- package/dist/run/record-attempt.js +30 -12
- package/dist/run/repair-attempt.d.ts +68 -0
- package/dist/run/repair-attempt.d.ts.map +1 -0
- package/dist/run/repair-attempt.js +180 -0
- package/dist/run/resolve-destination.d.ts +49 -0
- package/dist/run/resolve-destination.d.ts.map +1 -0
- package/dist/run/resolve-destination.js +76 -0
- package/dist/run/routing-docs.d.ts.map +1 -1
- package/dist/run/routing-docs.js +10 -5
- package/dist/run/run.d.ts +30 -1
- package/dist/run/run.d.ts.map +1 -1
- package/dist/run/run.js +94 -172
- package/dist/run/telemetry-row.d.ts +92 -0
- package/dist/run/telemetry-row.d.ts.map +1 -0
- package/dist/run/telemetry-row.js +81 -0
- package/dist/run/validate.d.ts +12 -1
- package/dist/run/validate.d.ts.map +1 -1
- package/dist/run/validate.js +31 -0
- package/dist/run/web-search-pricing.d.ts +43 -0
- package/dist/run/web-search-pricing.d.ts.map +1 -0
- package/dist/run/web-search-pricing.js +56 -0
- 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 +102 -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 +32 -20
- package/dist/status.d.ts.map +1 -1
- package/dist/status.js +51 -30
- 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 +21 -24
- package/dist/telemetry/attempt-meta.d.ts +76 -1
- package/dist/telemetry/attempt-meta.d.ts.map +1 -1
- package/dist/telemetry/attempt-meta.js +33 -1
- package/dist/telemetry/exporter-setup.d.ts +2 -0
- package/dist/telemetry/exporter-setup.d.ts.map +1 -1
- package/dist/telemetry/exporter-setup.js +6 -1
- 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 +25 -0
- package/dist/telemetry/grade-mappers.d.ts.map +1 -0
- package/dist/telemetry/grade-mappers.js +64 -0
- package/dist/telemetry/grades-sql.d.ts +56 -0
- package/dist/telemetry/grades-sql.d.ts.map +1 -0
- package/dist/telemetry/grades-sql.js +156 -0
- package/dist/telemetry/ingest-protocol.d.ts +55 -48
- package/dist/telemetry/ingest-protocol.d.ts.map +1 -1
- package/dist/telemetry/ingest-protocol.js +48 -83
- package/dist/telemetry/org-identity.d.ts +44 -0
- package/dist/telemetry/org-identity.d.ts.map +1 -0
- package/dist/telemetry/org-identity.js +98 -0
- package/dist/telemetry/route-registration.d.ts +48 -0
- package/dist/telemetry/route-registration.d.ts.map +1 -0
- package/dist/telemetry/route-registration.js +77 -0
- package/dist/telemetry/sinks.d.ts +10 -1
- package/dist/telemetry/sinks.d.ts.map +1 -1
- package/dist/telemetry/sinks.js +52 -6
- package/dist/telemetry/store-migrations.d.ts.map +1 -1
- package/dist/telemetry/store-migrations.js +64 -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 +45 -1
- package/dist/tenancy/api-key-format.d.ts.map +1 -1
- package/dist/tenancy/api-key-format.js +50 -1
- package/dist/types/provider.d.ts +23 -3
- package/dist/types/provider.d.ts.map +1 -1
- package/dist/types/provider.js +26 -0
- package/dist/types/route.d.ts +154 -2
- package/dist/types/route.d.ts.map +1 -1
- package/dist/types/telemetry.d.ts +73 -48
- 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 +181 -9
- package/docs/how-it-fits.md +3 -2
- package/docs/instrumentation.md +219 -46
- package/docs/llms.txt +158 -35
- package/docs/managed-serving.md +150 -0
- package/docs/mcp-oracle.md +322 -0
- package/docs/migration-playbook.md +5 -4
- package/docs/quickstart.md +263 -89
- package/package.json +18 -4
- package/registry/leaderboard.json +74 -0
- package/registry/registry.json +232 -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/feedback/feedback.d.ts +0 -35
- package/dist/feedback/feedback.d.ts.map +0 -1
- package/dist/feedback/feedback.js +0 -39
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CS-1 Chunk B — the masked-vs-unmasked value-accuracy arm (spec §7).
|
|
3
|
+
*
|
|
4
|
+
* Chunk A proved the load-bearing property: no detected span leaves (proof.ts,
|
|
5
|
+
* leakage-only, offline over captures). Chunk B answers the customer's second
|
|
6
|
+
* question — "did masking change the answer?" — by replaying the route's
|
|
7
|
+
* captures twice against the INCUMBENT model only:
|
|
8
|
+
* - control = the route with masking OFF (byte-identical to pre-CS-1)
|
|
9
|
+
* - treatment = the route's real `mask:` policy (mask → dispatch → rehydrate)
|
|
10
|
+
* and diffing per-sample quality with a paired-bootstrap CI, then gating
|
|
11
|
+
* promotion on the policy's `tolerance` block (value_accuracy_delta_max /
|
|
12
|
+
* conformance_delta_max). PR-as-actuator: a `mask.mode` promotion is a route
|
|
13
|
+
* bundle change whose PR body is this report — no silent promotion.
|
|
14
|
+
*
|
|
15
|
+
* RB-1 fence: this module ONLY CALLS the RB-1 replay/stats primitives
|
|
16
|
+
* (`replayVariant`, `pairedRegret`, `aggregateVariantMetrics`, `wilson95`). It
|
|
17
|
+
* does not restructure `engine.ts`/`replay.ts`/`stats.ts`. The mask arm is a
|
|
18
|
+
* standalone report (it composes the Chunk-A leak proof + the Chunk-B Δ), not a
|
|
19
|
+
* restructured `BakeoffArtifact` — flagged for the architect (P2).
|
|
20
|
+
*
|
|
21
|
+
* Counts-never-values: every field emitted here is a number, an enum, a policy
|
|
22
|
+
* hash, or a capture id — never a matched value (asserted by the
|
|
23
|
+
* receipt-invariant property test, extended in Chunk B to this report).
|
|
24
|
+
*/
|
|
25
|
+
import type { CaptureStore } from "../telemetry/capture";
|
|
26
|
+
import type { LoadedRoutes } from "../routes/loader";
|
|
27
|
+
import type { RunDeps } from "../run/run";
|
|
28
|
+
import { type ReplaySampleResult } from "../bakeoff/replay";
|
|
29
|
+
import type { ResolvedMaskPolicy, MaskTolerance } from "./types";
|
|
30
|
+
import { type MaskArmProof } from "./proof";
|
|
31
|
+
/** Minimum paired samples before the separation gate may say "promotable"
|
|
32
|
+
* (mirrors engine.ts's `nPaired >= 10` floor — a Δ over <10 pairs is noise). */
|
|
33
|
+
export declare const MASK_ARM_MIN_PAIRED = 10;
|
|
34
|
+
/** A single fixture whose quality dropped most under masking — id + magnitude
|
|
35
|
+
* only (spec §7.2 "the per-fixture worst offenders (fixture ids + types, never
|
|
36
|
+
* values)"). */
|
|
37
|
+
export interface MaskArmOffender {
|
|
38
|
+
readonly captureId: string;
|
|
39
|
+
readonly qualityDrop: number;
|
|
40
|
+
}
|
|
41
|
+
/** The masked-vs-unmasked Δ (spec §7). All counts/rates/CIs — never a value. */
|
|
42
|
+
export interface MaskArmDelta {
|
|
43
|
+
readonly policyHash: string;
|
|
44
|
+
readonly nPaired: number;
|
|
45
|
+
readonly controlValueAccuracyMean: number | null;
|
|
46
|
+
readonly treatmentValueAccuracyMean: number | null;
|
|
47
|
+
/** mean q(control) − q(treatment): how much masking dropped quality. */
|
|
48
|
+
readonly valueAccuracyDelta: number;
|
|
49
|
+
readonly valueAccuracyDeltaCi95: readonly [number, number];
|
|
50
|
+
readonly controlConformRate: number;
|
|
51
|
+
readonly treatmentConformRate: number;
|
|
52
|
+
readonly conformanceDelta: number;
|
|
53
|
+
readonly conformanceDeltaCi95: readonly [number, number];
|
|
54
|
+
readonly tolerance: MaskTolerance | null;
|
|
55
|
+
/** value-accuracy Δ CI upper bound within tolerance (CI not excluding zero harm). */
|
|
56
|
+
readonly valueAccuracyOk: boolean;
|
|
57
|
+
readonly conformanceOk: boolean;
|
|
58
|
+
/** promotable ⇒ gate clears AND enough pairs AND no leak (set by the caller). */
|
|
59
|
+
readonly promotable: boolean;
|
|
60
|
+
readonly worstOffenders: readonly MaskArmOffender[];
|
|
61
|
+
}
|
|
62
|
+
/** The masked-arm report — a bake-off report of `kind: mask-policy` (spec §7.1),
|
|
63
|
+
* the artifact that (a) renders as the promotion PR body, (b) maps to a
|
|
64
|
+
* `Receipt@v1 kind: masking-proof` (RP-0), (c) feeds the console Control card. */
|
|
65
|
+
export interface MaskArmReport {
|
|
66
|
+
readonly kind: "mask-policy";
|
|
67
|
+
readonly route: string;
|
|
68
|
+
readonly routeVersion: number;
|
|
69
|
+
readonly ranAt: string;
|
|
70
|
+
readonly policyHash: string;
|
|
71
|
+
readonly replayN: number;
|
|
72
|
+
readonly models: readonly {
|
|
73
|
+
readonly provider: string;
|
|
74
|
+
readonly model: string;
|
|
75
|
+
}[];
|
|
76
|
+
/** Chunk-A leak proof over the same captures — the load-bearing invariant. */
|
|
77
|
+
readonly proof: MaskArmProof;
|
|
78
|
+
/** Chunk-B value-accuracy Δ. */
|
|
79
|
+
readonly delta: MaskArmDelta;
|
|
80
|
+
}
|
|
81
|
+
/** Wrap a `LoadedRoutes` so the target route resolves with masking stripped —
|
|
82
|
+
* the control (unmasked) arm. Only `.mask` is cleared, and only for `route`;
|
|
83
|
+
* every other field and route is untouched, so the control arm is byte-identical
|
|
84
|
+
* to the pre-CS-1 path (the golden). */
|
|
85
|
+
export declare function stripMaskFromRoutes(routes: LoadedRoutes, route: string): LoadedRoutes;
|
|
86
|
+
/**
|
|
87
|
+
* Compute the masked-vs-unmasked Δ from two replay passes over the SAME captures
|
|
88
|
+
* (same incumbent model; masking the only difference). Pure — reuses stats.ts.
|
|
89
|
+
* `pairedRegret(treatment, control)` yields mean q(control) − q(treatment), i.e.
|
|
90
|
+
* the quality DROP caused by masking, with a seeded paired-bootstrap CI.
|
|
91
|
+
*/
|
|
92
|
+
export declare function computeMaskArmDelta(policy: ResolvedMaskPolicy, control: readonly ReplaySampleResult[], treatment: readonly ReplaySampleResult[]): MaskArmDelta;
|
|
93
|
+
export interface MaskArmBakeoffRequest {
|
|
94
|
+
readonly route: string;
|
|
95
|
+
readonly replayLast: number;
|
|
96
|
+
readonly envelopeUsd: number;
|
|
97
|
+
/** Injectable clock for deterministic `ranAt` in tests. */
|
|
98
|
+
readonly now?: () => Date;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Run the full masked-arm bake-off: replay the incumbent twice (control =
|
|
102
|
+
* unmasked, treatment = masked), diff, gate, and compose the report with the
|
|
103
|
+
* Chunk-A leak proof over the same captures. Real (billed) dispatches — the
|
|
104
|
+
* live run over the demo-rig / InferWealth corpus is deferred to a
|
|
105
|
+
* provider-keyed session; unit tests drive it with a fake adapter.
|
|
106
|
+
*/
|
|
107
|
+
export declare function runMaskArmBakeoff(deps: RunDeps, captures: CaptureStore, req: MaskArmBakeoffRequest): Promise<MaskArmReport>;
|
|
108
|
+
/** Render the masked-arm report as counts-only Markdown — the promotion PR body
|
|
109
|
+
* (spec §7.3) and the verification-doc artifact. Extends `formatMaskArmReport`
|
|
110
|
+
* (the Chunk-A leak block) with the Chunk-B Δ + separation gate. */
|
|
111
|
+
export declare function formatMaskArmReportFull(report: MaskArmReport): string;
|
|
112
|
+
//# sourceMappingURL=arm.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"arm.d.ts","sourceRoot":"","sources":["../../src/mask/arm.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAiB,KAAK,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAE3E,OAAO,KAAK,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACjE,OAAO,EAA4B,KAAK,YAAY,EAAE,MAAM,SAAS,CAAC;AAItE;mFACmF;AACnF,eAAO,MAAM,mBAAmB,KAAK,CAAC;AAItC;;gBAEgB;AAChB,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B;AAED,gFAAgF;AAChF,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,wBAAwB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjD,QAAQ,CAAC,0BAA0B,EAAE,MAAM,GAAG,IAAI,CAAC;IACnD,wEAAwE;IACxE,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,sBAAsB,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC3D,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,oBAAoB,EAAE,MAAM,CAAC;IACtC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,oBAAoB,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACzD,QAAQ,CAAC,SAAS,EAAE,aAAa,GAAG,IAAI,CAAC;IACzC,qFAAqF;IACrF,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAC;IAClC,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC;IAChC,iFAAiF;IACjF,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAC7B,QAAQ,CAAC,cAAc,EAAE,SAAS,eAAe,EAAE,CAAC;CACrD;AAED;;kFAEkF;AAClF,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,SAAS;QAAE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAClF,8EAA8E;IAC9E,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAC;IAC7B,gCAAgC;IAChC,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAC;CAC9B;AAED;;;wCAGwC;AACxC,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,GAAG,YAAY,CAOrF;AAaD;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,kBAAkB,EAC1B,OAAO,EAAE,SAAS,kBAAkB,EAAE,EACtC,SAAS,EAAE,SAAS,kBAAkB,EAAE,GACvC,YAAY,CA0Cd;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,2DAA2D;IAC3D,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC;CAC3B;AAED;;;;;;GAMG;AACH,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,OAAO,EACb,QAAQ,EAAE,YAAY,EACtB,GAAG,EAAE,qBAAqB,GACzB,OAAO,CAAC,aAAa,CAAC,CA0CxB;AAMD;;oEAEoE;AACpE,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM,CA8BrE"}
|
package/dist/mask/arm.js
ADDED
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* CS-1 Chunk B — the masked-vs-unmasked value-accuracy arm (spec §7).
|
|
4
|
+
*
|
|
5
|
+
* Chunk A proved the load-bearing property: no detected span leaves (proof.ts,
|
|
6
|
+
* leakage-only, offline over captures). Chunk B answers the customer's second
|
|
7
|
+
* question — "did masking change the answer?" — by replaying the route's
|
|
8
|
+
* captures twice against the INCUMBENT model only:
|
|
9
|
+
* - control = the route with masking OFF (byte-identical to pre-CS-1)
|
|
10
|
+
* - treatment = the route's real `mask:` policy (mask → dispatch → rehydrate)
|
|
11
|
+
* and diffing per-sample quality with a paired-bootstrap CI, then gating
|
|
12
|
+
* promotion on the policy's `tolerance` block (value_accuracy_delta_max /
|
|
13
|
+
* conformance_delta_max). PR-as-actuator: a `mask.mode` promotion is a route
|
|
14
|
+
* bundle change whose PR body is this report — no silent promotion.
|
|
15
|
+
*
|
|
16
|
+
* RB-1 fence: this module ONLY CALLS the RB-1 replay/stats primitives
|
|
17
|
+
* (`replayVariant`, `pairedRegret`, `aggregateVariantMetrics`, `wilson95`). It
|
|
18
|
+
* does not restructure `engine.ts`/`replay.ts`/`stats.ts`. The mask arm is a
|
|
19
|
+
* standalone report (it composes the Chunk-A leak proof + the Chunk-B Δ), not a
|
|
20
|
+
* restructured `BakeoffArtifact` — flagged for the architect (P2).
|
|
21
|
+
*
|
|
22
|
+
* Counts-never-values: every field emitted here is a number, an enum, a policy
|
|
23
|
+
* hash, or a capture id — never a matched value (asserted by the
|
|
24
|
+
* receipt-invariant property test, extended in Chunk B to this report).
|
|
25
|
+
*/
|
|
26
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
27
|
+
exports.MASK_ARM_MIN_PAIRED = void 0;
|
|
28
|
+
exports.stripMaskFromRoutes = stripMaskFromRoutes;
|
|
29
|
+
exports.computeMaskArmDelta = computeMaskArmDelta;
|
|
30
|
+
exports.runMaskArmBakeoff = runMaskArmBakeoff;
|
|
31
|
+
exports.formatMaskArmReportFull = formatMaskArmReportFull;
|
|
32
|
+
const replay_1 = require("../bakeoff/replay");
|
|
33
|
+
const stats_1 = require("../bakeoff/stats");
|
|
34
|
+
const proof_1 = require("./proof");
|
|
35
|
+
/** Slack for a floating-point threshold comparison — mirrors engine.ts's gate EPS. */
|
|
36
|
+
const GATE_EPS = 1e-9;
|
|
37
|
+
/** Minimum paired samples before the separation gate may say "promotable"
|
|
38
|
+
* (mirrors engine.ts's `nPaired >= 10` floor — a Δ over <10 pairs is noise). */
|
|
39
|
+
exports.MASK_ARM_MIN_PAIRED = 10;
|
|
40
|
+
/** How many worst-offending fixtures the report lists (ids + drop, never values). */
|
|
41
|
+
const WORST_OFFENDERS = 5;
|
|
42
|
+
/** Wrap a `LoadedRoutes` so the target route resolves with masking stripped —
|
|
43
|
+
* the control (unmasked) arm. Only `.mask` is cleared, and only for `route`;
|
|
44
|
+
* every other field and route is untouched, so the control arm is byte-identical
|
|
45
|
+
* to the pre-CS-1 path (the golden). */
|
|
46
|
+
function stripMaskFromRoutes(routes, route) {
|
|
47
|
+
const strip = (b) => b.route === route && b.mask !== undefined ? { ...b, mask: undefined } : b;
|
|
48
|
+
return {
|
|
49
|
+
get: (r) => strip(routes.get(r)),
|
|
50
|
+
list: () => routes.list().map(strip),
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
/** Per-sample quality forced to conformance only (value score dropped), so the
|
|
54
|
+
* shared `pairedRegret` bootstrap yields a conformance-specific Δ CI. */
|
|
55
|
+
function conformanceOnly(s) {
|
|
56
|
+
return { ...s, valueAccuracy: null };
|
|
57
|
+
}
|
|
58
|
+
function meanOrNull(xs) {
|
|
59
|
+
const nums = xs.filter((x) => x !== null);
|
|
60
|
+
return nums.length === 0 ? null : nums.reduce((a, b) => a + b, 0) / nums.length;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Compute the masked-vs-unmasked Δ from two replay passes over the SAME captures
|
|
64
|
+
* (same incumbent model; masking the only difference). Pure — reuses stats.ts.
|
|
65
|
+
* `pairedRegret(treatment, control)` yields mean q(control) − q(treatment), i.e.
|
|
66
|
+
* the quality DROP caused by masking, with a seeded paired-bootstrap CI.
|
|
67
|
+
*/
|
|
68
|
+
function computeMaskArmDelta(policy, control, treatment) {
|
|
69
|
+
const va = (0, stats_1.pairedRegret)(treatment, control);
|
|
70
|
+
const conf = (0, stats_1.pairedRegret)(treatment.map(conformanceOnly), control.map(conformanceOnly));
|
|
71
|
+
const controlMetrics = (0, stats_1.aggregateVariantMetrics)("control", control);
|
|
72
|
+
const treatmentMetrics = (0, stats_1.aggregateVariantMetrics)("masked", treatment);
|
|
73
|
+
const tolerance = policy.policy.tolerance ?? null;
|
|
74
|
+
const valueAccuracyOk = tolerance === null ? false : va.regretCi95[1] <= tolerance.value_accuracy_delta_max + GATE_EPS;
|
|
75
|
+
const conformanceOk = tolerance === null ? false : conf.regretMean <= tolerance.conformance_delta_max + GATE_EPS;
|
|
76
|
+
const promotable = valueAccuracyOk && conformanceOk && va.nPaired >= exports.MASK_ARM_MIN_PAIRED;
|
|
77
|
+
// Worst offenders: per-capture quality drop q(control) − q(treatment), the
|
|
78
|
+
// fixtures masking hurt most — ids + magnitude only (spec §7.2).
|
|
79
|
+
const controlByCapture = new Map(control.map((s) => [s.captureId, s]));
|
|
80
|
+
const drops = [];
|
|
81
|
+
for (const t of treatment) {
|
|
82
|
+
const c = controlByCapture.get(t.captureId);
|
|
83
|
+
if (c === undefined)
|
|
84
|
+
continue;
|
|
85
|
+
const drop = (c.valueAccuracy ?? (c.conform ? 1 : 0)) - (t.valueAccuracy ?? (t.conform ? 1 : 0));
|
|
86
|
+
if (drop > 0)
|
|
87
|
+
drops.push({ captureId: t.captureId, qualityDrop: drop });
|
|
88
|
+
}
|
|
89
|
+
drops.sort((a, b) => b.qualityDrop - a.qualityDrop);
|
|
90
|
+
return {
|
|
91
|
+
policyHash: policy.policyHash,
|
|
92
|
+
nPaired: va.nPaired,
|
|
93
|
+
controlValueAccuracyMean: meanOrNull(control.map((s) => s.valueAccuracy)),
|
|
94
|
+
treatmentValueAccuracyMean: meanOrNull(treatment.map((s) => s.valueAccuracy)),
|
|
95
|
+
valueAccuracyDelta: va.regretMean,
|
|
96
|
+
valueAccuracyDeltaCi95: va.regretCi95,
|
|
97
|
+
controlConformRate: controlMetrics.conformRate,
|
|
98
|
+
treatmentConformRate: treatmentMetrics.conformRate,
|
|
99
|
+
conformanceDelta: conf.regretMean,
|
|
100
|
+
conformanceDeltaCi95: conf.regretCi95,
|
|
101
|
+
tolerance,
|
|
102
|
+
valueAccuracyOk,
|
|
103
|
+
conformanceOk,
|
|
104
|
+
promotable,
|
|
105
|
+
worstOffenders: drops.slice(0, WORST_OFFENDERS),
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Run the full masked-arm bake-off: replay the incumbent twice (control =
|
|
110
|
+
* unmasked, treatment = masked), diff, gate, and compose the report with the
|
|
111
|
+
* Chunk-A leak proof over the same captures. Real (billed) dispatches — the
|
|
112
|
+
* live run over the demo-rig / InferWealth corpus is deferred to a
|
|
113
|
+
* provider-keyed session; unit tests drive it with a fake adapter.
|
|
114
|
+
*/
|
|
115
|
+
async function runMaskArmBakeoff(deps, captures, req) {
|
|
116
|
+
const bundle = deps.routes.get(req.route);
|
|
117
|
+
if (bundle.mask === undefined) {
|
|
118
|
+
throw new Error(`route "${req.route}" has no active mask: policy (mode: mask) — add one before running the masked arm`);
|
|
119
|
+
}
|
|
120
|
+
const policy = bundle.mask;
|
|
121
|
+
const replayReq = {
|
|
122
|
+
route: req.route,
|
|
123
|
+
variant: "default",
|
|
124
|
+
lastN: req.replayLast,
|
|
125
|
+
envelopeUsd: req.envelopeUsd,
|
|
126
|
+
};
|
|
127
|
+
// Treatment: the route as configured (masking ON). Control: masking stripped.
|
|
128
|
+
const treatment = await (0, replay_1.replayVariant)(deps, captures, replayReq);
|
|
129
|
+
const control = await (0, replay_1.replayVariant)({ ...deps, routes: stripMaskFromRoutes(deps.routes, req.route) }, captures, replayReq);
|
|
130
|
+
// The Chunk-A leak proof over the same captures — the invariant that gates all.
|
|
131
|
+
const proof = (0, proof_1.proveMaskArmFromCaptures)(captures.readLast(req.route, req.replayLast), policy);
|
|
132
|
+
const baseDelta = computeMaskArmDelta(policy, control, treatment);
|
|
133
|
+
// A leak voids promotion regardless of the Δ (fail closed on the invariant).
|
|
134
|
+
const delta = { ...baseDelta, promotable: baseDelta.promotable && proof.proven };
|
|
135
|
+
const incumbent = bundle.candidates[0];
|
|
136
|
+
return {
|
|
137
|
+
kind: "mask-policy",
|
|
138
|
+
route: req.route,
|
|
139
|
+
routeVersion: bundle.version,
|
|
140
|
+
ranAt: (req.now ?? (() => new Date()))().toISOString(),
|
|
141
|
+
policyHash: policy.policyHash,
|
|
142
|
+
replayN: proof.samples,
|
|
143
|
+
models: incumbent !== undefined ? [{ provider: incumbent.provider, model: incumbent.model }] : [],
|
|
144
|
+
proof,
|
|
145
|
+
delta,
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
function pct(x) {
|
|
149
|
+
return (x * 100).toFixed(2);
|
|
150
|
+
}
|
|
151
|
+
/** Render the masked-arm report as counts-only Markdown — the promotion PR body
|
|
152
|
+
* (spec §7.3) and the verification-doc artifact. Extends `formatMaskArmReport`
|
|
153
|
+
* (the Chunk-A leak block) with the Chunk-B Δ + separation gate. */
|
|
154
|
+
function formatMaskArmReportFull(report) {
|
|
155
|
+
const d = report.delta;
|
|
156
|
+
const lines = [];
|
|
157
|
+
lines.push(`### Masked-arm report — kind: mask-policy — route \`${report.route}\` v${report.routeVersion}`);
|
|
158
|
+
lines.push("");
|
|
159
|
+
lines.push(`- policy: \`${report.policyHash.slice(0, 12)}…\``);
|
|
160
|
+
lines.push(`- samples (leak proof): ${report.proof.samples}`);
|
|
161
|
+
lines.push(`- paired samples (Δ arm): ${d.nPaired}`);
|
|
162
|
+
lines.push(`- masked-arm leaks: ${report.proof.maskedLeaks.reduce((a, f) => a + f.count, 0)} (${report.proof.proven ? "PROVEN none" : "LEAK"})`);
|
|
163
|
+
lines.push("");
|
|
164
|
+
lines.push("| metric | control (unmasked) | masked (treatment) | Δ | CI 95% | budget | within |");
|
|
165
|
+
lines.push("|---|---|---|---|---|---|---|");
|
|
166
|
+
const vaBudget = d.tolerance !== null ? d.tolerance.value_accuracy_delta_max.toFixed(3) : "—";
|
|
167
|
+
const confBudget = d.tolerance !== null ? d.tolerance.conformance_delta_max.toFixed(3) : "—";
|
|
168
|
+
lines.push(`| value_accuracy | ${d.controlValueAccuracyMean === null ? "n/a" : d.controlValueAccuracyMean.toFixed(3)} | ${d.treatmentValueAccuracyMean === null ? "n/a" : d.treatmentValueAccuracyMean.toFixed(3)} | ${d.valueAccuracyDelta.toFixed(3)} | [${d.valueAccuracyDeltaCi95[0].toFixed(3)}, ${d.valueAccuracyDeltaCi95[1].toFixed(3)}] | ${vaBudget} | ${d.valueAccuracyOk ? "yes" : "NO"} |`);
|
|
169
|
+
lines.push(`| conformance | ${pct(d.controlConformRate)}% | ${pct(d.treatmentConformRate)}% | ${d.conformanceDelta.toFixed(3)} | [${d.conformanceDeltaCi95[0].toFixed(3)}, ${d.conformanceDeltaCi95[1].toFixed(3)}] | ${confBudget} | ${d.conformanceOk ? "yes" : "NO"} |`);
|
|
170
|
+
lines.push("");
|
|
171
|
+
lines.push(`**Gate: ${d.promotable ? "promotable" : "blocked-by-evidence"}** (n_paired ${d.nPaired}${d.nPaired < exports.MASK_ARM_MIN_PAIRED ? ` < ${exports.MASK_ARM_MIN_PAIRED} floor` : ""}). PR-as-actuator — promotion is a route-bundle PR, never silent.`);
|
|
172
|
+
if (d.worstOffenders.length > 0) {
|
|
173
|
+
lines.push("");
|
|
174
|
+
lines.push("Worst-offending fixtures (ids + quality drop, never values):");
|
|
175
|
+
for (const o of d.worstOffenders)
|
|
176
|
+
lines.push(`- \`${o.captureId}\` · −${o.qualityDrop.toFixed(3)}`);
|
|
177
|
+
}
|
|
178
|
+
return lines.join("\n");
|
|
179
|
+
}
|
package/dist/mask/index.d.ts
CHANGED
|
@@ -18,4 +18,6 @@ export { createMaskSeam, resetMaskWarningsForTest } from "./seam";
|
|
|
18
18
|
export type { MaskSeam, MaskRequestOutcome } from "./seam";
|
|
19
19
|
export { proveMaskedArm, formatMaskArmReport, proveMaskArmFromCaptures, collectStringLeaves } from "./proof";
|
|
20
20
|
export type { MaskArmProof } from "./proof";
|
|
21
|
+
export { runMaskArmBakeoff, computeMaskArmDelta, formatMaskArmReportFull, stripMaskFromRoutes, MASK_ARM_MIN_PAIRED, } from "./arm";
|
|
22
|
+
export type { MaskArmReport, MaskArmDelta, MaskArmOffender, MaskArmBakeoffRequest } from "./arm";
|
|
21
23
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/mask/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/mask/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,cAAc,SAAS,CAAC;AACxB,OAAO,EAAE,iBAAiB,EAAE,uBAAuB,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AACxG,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAC5D,YAAY,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAC/F,YAAY,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACxC,OAAO,EACL,QAAQ,EACR,SAAS,EACT,aAAa,EACb,cAAc,EACd,sBAAsB,GACvB,MAAM,SAAS,CAAC;AACjB,YAAY,EAAE,UAAU,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACxE,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC1D,YAAY,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,wBAAwB,EAAE,MAAM,QAAQ,CAAC;AAClE,YAAY,EAAE,QAAQ,EAAE,kBAAkB,EAAE,MAAM,QAAQ,CAAC;AAC3D,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,wBAAwB,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAC7G,YAAY,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/mask/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,cAAc,SAAS,CAAC;AACxB,OAAO,EAAE,iBAAiB,EAAE,uBAAuB,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AACxG,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAC5D,YAAY,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAC/F,YAAY,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACxC,OAAO,EACL,QAAQ,EACR,SAAS,EACT,aAAa,EACb,cAAc,EACd,sBAAsB,GACvB,MAAM,SAAS,CAAC;AACjB,YAAY,EAAE,UAAU,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACxE,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC1D,YAAY,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,wBAAwB,EAAE,MAAM,QAAQ,CAAC;AAClE,YAAY,EAAE,QAAQ,EAAE,kBAAkB,EAAE,MAAM,QAAQ,CAAC;AAC3D,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,wBAAwB,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAC7G,YAAY,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,uBAAuB,EACvB,mBAAmB,EACnB,mBAAmB,GACpB,MAAM,OAAO,CAAC;AACf,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,OAAO,CAAC"}
|
package/dist/mask/index.js
CHANGED
|
@@ -14,7 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
exports.collectStringLeaves = exports.proveMaskArmFromCaptures = exports.formatMaskArmReport = exports.proveMaskedArm = exports.resetMaskWarningsForTest = exports.createMaskSeam = exports.rollupFindings = exports.summarizeMask = exports.createStreamRehydrator = exports.rehydrateValue = exports.rehydrateText = exports.maskInput = exports.maskText = exports.tokenTypeLabel = exports.MAX_TOKEN_LENGTH = exports.MASK_TOKEN_PATTERN = exports.createRunVault = exports.resolveFieldTargets = exports.detectSpans = exports.parseDictionary = exports.parseMaskPolicy = exports.validateMaskPolicyShape = exports.resolveMaskPolicy = void 0;
|
|
17
|
+
exports.MASK_ARM_MIN_PAIRED = exports.stripMaskFromRoutes = exports.formatMaskArmReportFull = exports.computeMaskArmDelta = exports.runMaskArmBakeoff = exports.collectStringLeaves = exports.proveMaskArmFromCaptures = exports.formatMaskArmReport = exports.proveMaskedArm = exports.resetMaskWarningsForTest = exports.createMaskSeam = exports.rollupFindings = exports.summarizeMask = exports.createStreamRehydrator = exports.rehydrateValue = exports.rehydrateText = exports.maskInput = exports.maskText = exports.tokenTypeLabel = exports.MAX_TOKEN_LENGTH = exports.MASK_TOKEN_PATTERN = exports.createRunVault = exports.resolveFieldTargets = exports.detectSpans = exports.parseDictionary = exports.parseMaskPolicy = exports.validateMaskPolicyShape = exports.resolveMaskPolicy = void 0;
|
|
18
18
|
/**
|
|
19
19
|
* CS-1 Proven Masking — module surface (WIRED 2026-08-24, CS-1 Chunk A).
|
|
20
20
|
* Wired into the SDK via the run/dispatch seam (src/run/run.ts) and the route
|
|
@@ -52,3 +52,9 @@ Object.defineProperty(exports, "proveMaskedArm", { enumerable: true, get: functi
|
|
|
52
52
|
Object.defineProperty(exports, "formatMaskArmReport", { enumerable: true, get: function () { return proof_1.formatMaskArmReport; } });
|
|
53
53
|
Object.defineProperty(exports, "proveMaskArmFromCaptures", { enumerable: true, get: function () { return proof_1.proveMaskArmFromCaptures; } });
|
|
54
54
|
Object.defineProperty(exports, "collectStringLeaves", { enumerable: true, get: function () { return proof_1.collectStringLeaves; } });
|
|
55
|
+
var arm_1 = require("./arm");
|
|
56
|
+
Object.defineProperty(exports, "runMaskArmBakeoff", { enumerable: true, get: function () { return arm_1.runMaskArmBakeoff; } });
|
|
57
|
+
Object.defineProperty(exports, "computeMaskArmDelta", { enumerable: true, get: function () { return arm_1.computeMaskArmDelta; } });
|
|
58
|
+
Object.defineProperty(exports, "formatMaskArmReportFull", { enumerable: true, get: function () { return arm_1.formatMaskArmReportFull; } });
|
|
59
|
+
Object.defineProperty(exports, "stripMaskFromRoutes", { enumerable: true, get: function () { return arm_1.stripMaskFromRoutes; } });
|
|
60
|
+
Object.defineProperty(exports, "MASK_ARM_MIN_PAIRED", { enumerable: true, get: function () { return arm_1.MASK_ARM_MIN_PAIRED; } });
|
|
@@ -1,11 +1,19 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* CS-1 — `modelrig bakeoff --mask-policy <route>` handler (spec §7). Extracted
|
|
3
|
-
* from cli.ts to keep it under the 700-LOC cap.
|
|
4
|
-
*
|
|
5
|
-
*
|
|
3
|
+
* from cli.ts to keep it under the 700-LOC cap.
|
|
4
|
+
*
|
|
5
|
+
* Chunk A: prove, via the shared detector, that masking leaves NO detected span
|
|
6
|
+
* in the masked arm (offline over captures — no dispatch). Chunk B COMPLETES the
|
|
7
|
+
* command: replay the route's captures twice against the incumbent — unmasked
|
|
8
|
+
* (control) vs masked (treatment) — and report the value-accuracy Δ + CI + the
|
|
9
|
+
* separation gate against the policy's `tolerance` block. Exit 1 ONLY when a
|
|
10
|
+
* detected span leaks (the load-bearing invariant); a blocked-by-evidence Δ is a
|
|
11
|
+
* valid report — promotion is a route-bundle PR, never a silent CLI side effect.
|
|
12
|
+
*
|
|
13
|
+
* `--leak-only` runs just the Chunk-A offline proof (no billed dispatch).
|
|
6
14
|
* Additive — it does NOT touch the RB-1 replay engine (RB-1 fence).
|
|
7
15
|
*/
|
|
8
16
|
import type { RigConfig } from "../config";
|
|
9
17
|
import type { Flags } from "../cli";
|
|
10
|
-
export declare function runMaskPolicyProofCli(config: RigConfig, flags: Flags, route: string): number
|
|
18
|
+
export declare function runMaskPolicyProofCli(config: RigConfig, flags: Flags, route: string): Promise<number>;
|
|
11
19
|
//# sourceMappingURL=mask-policy-cli.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mask-policy-cli.d.ts","sourceRoot":"","sources":["../../src/mask/mask-policy-cli.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"mask-policy-cli.d.ts","sourceRoot":"","sources":["../../src/mask/mask-policy-cli.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAQpC,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,SAAS,EACjB,KAAK,EAAE,KAAK,EACZ,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,MAAM,CAAC,CAkCjB"}
|
|
@@ -1,18 +1,28 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/**
|
|
3
3
|
* CS-1 — `modelrig bakeoff --mask-policy <route>` handler (spec §7). Extracted
|
|
4
|
-
* from cli.ts to keep it under the 700-LOC cap.
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* from cli.ts to keep it under the 700-LOC cap.
|
|
5
|
+
*
|
|
6
|
+
* Chunk A: prove, via the shared detector, that masking leaves NO detected span
|
|
7
|
+
* in the masked arm (offline over captures — no dispatch). Chunk B COMPLETES the
|
|
8
|
+
* command: replay the route's captures twice against the incumbent — unmasked
|
|
9
|
+
* (control) vs masked (treatment) — and report the value-accuracy Δ + CI + the
|
|
10
|
+
* separation gate against the policy's `tolerance` block. Exit 1 ONLY when a
|
|
11
|
+
* detected span leaks (the load-bearing invariant); a blocked-by-evidence Δ is a
|
|
12
|
+
* valid report — promotion is a route-bundle PR, never a silent CLI side effect.
|
|
13
|
+
*
|
|
14
|
+
* `--leak-only` runs just the Chunk-A offline proof (no billed dispatch).
|
|
7
15
|
* Additive — it does NOT touch the RB-1 replay engine (RB-1 fence).
|
|
8
16
|
*/
|
|
9
17
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
18
|
exports.runMaskPolicyProofCli = runMaskPolicyProofCli;
|
|
19
|
+
const index_1 = require("../index");
|
|
11
20
|
const loader_1 = require("../routes/loader");
|
|
12
21
|
const rawonly_1 = require("../run/rawonly");
|
|
13
22
|
const capture_1 = require("../telemetry/capture");
|
|
14
23
|
const proof_1 = require("./proof");
|
|
15
|
-
|
|
24
|
+
const arm_1 = require("./arm");
|
|
25
|
+
async function runMaskPolicyProofCli(config, flags, route) {
|
|
16
26
|
const bundle = (0, loader_1.loadRoutes)((0, rawonly_1.requireRoutesDir)(config, "modelrig bakeoff")).get(route);
|
|
17
27
|
if (bundle.mask === undefined) {
|
|
18
28
|
throw new Error(`route "${route}" has no active mask: policy (mode: mask) — add one before proving the masked arm`);
|
|
@@ -21,13 +31,28 @@ function runMaskPolicyProofCli(config, flags, route) {
|
|
|
21
31
|
const n = nRaw !== undefined ? Number(nRaw) : 25;
|
|
22
32
|
if (!Number.isInteger(n) || n < 1)
|
|
23
33
|
throw new Error("--replay-last must be a positive integer");
|
|
24
|
-
|
|
34
|
+
// --leak-only: the offline invariant proof, NO billed dispatch (Chunk-A behaviour).
|
|
35
|
+
if (flags.bare.has("leak-only")) {
|
|
36
|
+
const captures = (0, capture_1.openCaptureStore)(config.telemetryDbPath);
|
|
37
|
+
try {
|
|
38
|
+
const proof = (0, proof_1.proveMaskArmFromCaptures)(captures.readLast(route, n), bundle.mask);
|
|
39
|
+
console.log((0, proof_1.formatMaskArmReport)(proof));
|
|
40
|
+
return proof.proven ? 0 : 1;
|
|
41
|
+
}
|
|
42
|
+
finally {
|
|
43
|
+
captures.close();
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
// Full masked-arm bake-off (spec §7): leak proof + value-accuracy Δ over the
|
|
47
|
+
// incumbent (real, billed replays). Live runs over the demo-rig / InferWealth
|
|
48
|
+
// corpus are deferred to a provider-keyed session (verification doc).
|
|
49
|
+
const rig = (0, index_1.createRig)(config);
|
|
25
50
|
try {
|
|
26
|
-
const
|
|
27
|
-
console.log((0,
|
|
28
|
-
return proof.proven ? 0 : 1;
|
|
51
|
+
const report = await rig.maskArm(route, { replayLast: n });
|
|
52
|
+
console.log((0, arm_1.formatMaskArmReportFull)(report));
|
|
53
|
+
return report.proof.proven ? 0 : 1;
|
|
29
54
|
}
|
|
30
55
|
finally {
|
|
31
|
-
|
|
56
|
+
await rig.close();
|
|
32
57
|
}
|
|
33
58
|
}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PSR-1 — the assembly-manifest model (spec §2.1, authoring-guide §2–§3).
|
|
3
|
+
*
|
|
4
|
+
* A prompt in ModelRig is TWO things: the authored `template` text and the
|
|
5
|
+
* `manifest` — the ordered recipe for assembling the final prompt at call time.
|
|
6
|
+
* This module is the **structure-only** manifest: its `Slot[]` records HOW each
|
|
7
|
+
* part of the prompt is filled, never the filled value (the privacy guarantee —
|
|
8
|
+
* a `dynamic·tool` slot names `search_tickets`, never what it returned).
|
|
9
|
+
*
|
|
10
|
+
* PSR-1 is ZERO-DDL and validate-only: nothing here serves or stores a version.
|
|
11
|
+
* It exists to prove the model against real prompts (the InferWealth inference)
|
|
12
|
+
* and a hand-authored doc (ADJ-1) before PSR-2 builds the `prompt_versions`
|
|
13
|
+
* store. Pure + dependency-free (no YAML dep — the authoring doc is accepted as
|
|
14
|
+
* JSON per §7; YAML is an optional future add).
|
|
15
|
+
*/
|
|
16
|
+
/** A slot is either authored text (`static`) or filled at run time (`dynamic`). */
|
|
17
|
+
export type SlotKind = "static" | "dynamic";
|
|
18
|
+
/** How a `dynamic` slot is filled (authoring-guide §2). Never the value. */
|
|
19
|
+
export type DynamicSourceKind = "tool" | "cache" | "upstream" | "variable";
|
|
20
|
+
/** Cache placement for a slot's content — `prefix` puts it at the front so the
|
|
21
|
+
* provider caches it across calls (maps to inferences.cache_key / prefix
|
|
22
|
+
* fingerprint); `none` is uncached. */
|
|
23
|
+
export type CachePolicy = "prefix" | "none";
|
|
24
|
+
/** Which authored field a `static` slot pulls its text from when it is not
|
|
25
|
+
* inlined (authoring-guide §3: the first static slot is `from: system`, the
|
|
26
|
+
* task instructions are `from: template`). */
|
|
27
|
+
export type StaticFrom = "system" | "template";
|
|
28
|
+
/** A `dynamic` slot's fill declaration — the source kind, the reference it
|
|
29
|
+
* resolves (tool name / cache handle / upstream step key / variable name), and
|
|
30
|
+
* an optional cache policy. Structure only; carries no resolved data (D6). */
|
|
31
|
+
export interface DynamicSource {
|
|
32
|
+
readonly kind: DynamicSourceKind;
|
|
33
|
+
readonly ref: string;
|
|
34
|
+
readonly cache_policy?: CachePolicy;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* One slot in the assembly manifest.
|
|
38
|
+
*
|
|
39
|
+
* A `static` slot carries EITHER inline `text` OR a `from` reference to the
|
|
40
|
+
* doc's authored `system` / `template` field — exactly one (text XOR from;
|
|
41
|
+
* authoring-guide §3 uses `from`, spec §2.1 uses inline `text` — both are
|
|
42
|
+
* reconciled here). A `dynamic` slot carries a `source`.
|
|
43
|
+
*/
|
|
44
|
+
export interface Slot {
|
|
45
|
+
readonly id: string;
|
|
46
|
+
readonly kind: SlotKind;
|
|
47
|
+
/** static only — inline authored text (XOR `from`). */
|
|
48
|
+
readonly text?: string;
|
|
49
|
+
/** static only — pull the text from the doc's `system`/`template` (XOR `text`). */
|
|
50
|
+
readonly from?: StaticFrom;
|
|
51
|
+
/** dynamic only — how the slot is filled at run time. */
|
|
52
|
+
readonly source?: DynamicSource;
|
|
53
|
+
}
|
|
54
|
+
/** The assembly manifest — an ordered list of slots; list order = send order.
|
|
55
|
+
* No resolved values are ever present (structure only, D6). */
|
|
56
|
+
export interface Manifest {
|
|
57
|
+
readonly slots: readonly Slot[];
|
|
58
|
+
}
|
|
59
|
+
/** Result of {@link validateManifest} — a discriminated union so callers get the
|
|
60
|
+
* narrowed `Manifest` on success and a teaching error list on failure. */
|
|
61
|
+
export type ManifestValidation = {
|
|
62
|
+
readonly ok: true;
|
|
63
|
+
readonly manifest: Manifest;
|
|
64
|
+
} | {
|
|
65
|
+
readonly ok: false;
|
|
66
|
+
readonly errors: readonly string[];
|
|
67
|
+
};
|
|
68
|
+
/** Validate an untrusted value as a {@link Manifest} (spec §4). Rejects: an
|
|
69
|
+
* unknown slot kind, a `static` slot with BOTH or NEITHER `text`/`from`, a
|
|
70
|
+
* `dynamic` slot missing its `source` (or with a bad source kind / empty ref /
|
|
71
|
+
* bad cache_policy), a slot carrying fields of the wrong kind, and duplicate
|
|
72
|
+
* slot ids. Never throws — returns a result. */
|
|
73
|
+
export declare function validateManifest(input: unknown): ManifestValidation;
|
|
74
|
+
/** Throwing form of {@link validateManifest} — returns the narrowed manifest or
|
|
75
|
+
* throws with the joined error list. Use where an invalid manifest is a bug the
|
|
76
|
+
* caller wants surfaced (tests, the emit path's guard). */
|
|
77
|
+
export declare function assertValidManifest(input: unknown): Manifest;
|
|
78
|
+
/**
|
|
79
|
+
* Reduce a validated {@link Manifest} to ITS CANONICAL SHAPE — the ONE clean
|
|
80
|
+
* projection PSR-2 persists (spec §4 "re-validate + normalize on ingest").
|
|
81
|
+
*
|
|
82
|
+
* WHY (a PSR-1 QA finding): {@link validateManifest} NARROWS an untrusted value
|
|
83
|
+
* to `Manifest` but casts `slots as Slot[]` — it does NOT strip unknown keys, so
|
|
84
|
+
* a raw artifact blob can carry extra fields (`text` alongside a `from`, a stray
|
|
85
|
+
* `note`, a `source` on a static slot) that pass validation and would be stored
|
|
86
|
+
* verbatim. The ingest path (prompt-ingest.ts) must NEVER trust the artifact blob
|
|
87
|
+
* as-is: it re-validates AND normalizes here so `template_sha` (computed over the
|
|
88
|
+
* normalized manifest) is stable — identical content always dedupes to one row,
|
|
89
|
+
* regardless of incidental key noise in the source artifact.
|
|
90
|
+
*
|
|
91
|
+
* Each slot is rebuilt from scratch keeping ONLY the canonical keys:
|
|
92
|
+
* static → { id, kind, text } XOR { id, kind, from }
|
|
93
|
+
* dynamic → { id, kind, source: { kind, ref, cache_policy? } }
|
|
94
|
+
* Slot order is preserved (order = send order, D6). The rebuilt manifest is
|
|
95
|
+
* re-validated ({@link assertValidManifest}) so a caller that skipped validation
|
|
96
|
+
* still cannot persist a malformed shape.
|
|
97
|
+
*/
|
|
98
|
+
export declare function normalizeManifest(input: Manifest): Manifest;
|
|
99
|
+
/** The declared authoring document (authoring-guide §3). A superset of the
|
|
100
|
+
* manifest: the authored `system`/`template` text a `from`-slot references, plus
|
|
101
|
+
* the route metadata PSR-2/PSR-3 persist. PSR-1 reads only `manifest.slots`
|
|
102
|
+
* (validating that every `from` resolves to a present field). */
|
|
103
|
+
export interface AuthoringDoc {
|
|
104
|
+
readonly route?: string;
|
|
105
|
+
readonly segment?: string;
|
|
106
|
+
readonly system?: string;
|
|
107
|
+
readonly template?: string;
|
|
108
|
+
readonly manifest?: {
|
|
109
|
+
readonly slots?: unknown;
|
|
110
|
+
};
|
|
111
|
+
readonly output_schema?: unknown;
|
|
112
|
+
readonly candidates?: unknown;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* ADJ-1 — the "author from scratch" on-ramp. Parse a declared authoring doc
|
|
116
|
+
* (authoring-guide §3) into a validated {@link Manifest}. Accepts the doc as a
|
|
117
|
+
* JSON string OR an already-parsed object (§7: the MCP tool takes JSON; YAML is
|
|
118
|
+
* an optional future add and is NOT parsed here — a YAML string throws a
|
|
119
|
+
* teaching error). Beyond {@link validateManifest} it cross-checks that every
|
|
120
|
+
* `static` slot's `from: system|template` resolves to a present top-level field,
|
|
121
|
+
* so an author cannot reference authored text the doc does not carry.
|
|
122
|
+
*
|
|
123
|
+
* Structure-only: the returned manifest's slots are the authored slots verbatim
|
|
124
|
+
* (a `from`-slot keeps its `from`; the authored text is NOT inlined), so
|
|
125
|
+
* `parseAuthoringDoc` round-trips a hand-authored doc.
|
|
126
|
+
*/
|
|
127
|
+
export declare function parseAuthoringDoc(input: string | AuthoringDoc): Manifest;
|
|
128
|
+
//# sourceMappingURL=manifest.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../src/prompts/manifest.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,mFAAmF;AACnF,MAAM,MAAM,QAAQ,GAAG,QAAQ,GAAG,SAAS,CAAC;AAE5C,4EAA4E;AAC5E,MAAM,MAAM,iBAAiB,GAAG,MAAM,GAAG,OAAO,GAAG,UAAU,GAAG,UAAU,CAAC;AAE3E;;uCAEuC;AACvC,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,MAAM,CAAC;AAE5C;;8CAE8C;AAC9C,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,UAAU,CAAC;AAE/C;;8EAE8E;AAC9E,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,EAAE,iBAAiB,CAAC;IACjC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,YAAY,CAAC,EAAE,WAAW,CAAC;CACrC;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,IAAI;IACnB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IACxB,uDAAuD;IACvD,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,mFAAmF;IACnF,QAAQ,CAAC,IAAI,CAAC,EAAE,UAAU,CAAC;IAC3B,yDAAyD;IACzD,QAAQ,CAAC,MAAM,CAAC,EAAE,aAAa,CAAC;CACjC;AAED;+DAC+D;AAC/D,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,KAAK,EAAE,SAAS,IAAI,EAAE,CAAC;CACjC;AAED;0EAC0E;AAC1E,MAAM,MAAM,kBAAkB,GAC1B;IAAE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAA;CAAE,GAClD;IAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,CAAC;AAmB/D;;;;gDAIgD;AAChD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,kBAAkB,CA2DnE;AAkBD;;2DAE2D;AAC3D,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,QAAQ,CAM5D;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,QAAQ,GAAG,QAAQ,CAiB3D;AAED;;;iEAGiE;AACjE,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,QAAQ,CAAC,EAAE;QAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;IACjD,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC;IACjC,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC;CAC/B;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,YAAY,GAAG,QAAQ,CAmCxE"}
|