@davesheffer/hunch 1.7.0 → 1.7.1

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.
Files changed (63) hide show
  1. package/README.md +214 -0
  2. package/bench/constitution-exp03-v1.json +70 -0
  3. package/dist/cli/index.js +1203 -24
  4. package/dist/constitution/adapters.js +487 -0
  5. package/dist/constitution/behaviorAttestationBinding.js +17 -0
  6. package/dist/constitution/behaviorEvaluator.js +220 -0
  7. package/dist/constitution/behaviorProof.js +205 -0
  8. package/dist/constitution/behaviorWorkspace.js +124 -0
  9. package/dist/constitution/bootstrap.js +133 -0
  10. package/dist/constitution/canonical.js +51 -0
  11. package/dist/constitution/card.js +133 -0
  12. package/dist/constitution/compiler.js +176 -0
  13. package/dist/constitution/composition.js +101 -0
  14. package/dist/constitution/corpus.js +58 -0
  15. package/dist/constitution/delta.js +154 -0
  16. package/dist/constitution/disposition.js +141 -0
  17. package/dist/constitution/evaluator.js +435 -0
  18. package/dist/constitution/experiment.js +948 -0
  19. package/dist/constitution/experimentRunner.js +344 -0
  20. package/dist/constitution/g2.js +291 -0
  21. package/dist/constitution/g2BehaviorAttestation.js +209 -0
  22. package/dist/constitution/g2BehaviorCandidates.js +703 -0
  23. package/dist/constitution/g2BehaviorDependencies.js +379 -0
  24. package/dist/constitution/g2BehaviorMaterialization.js +171 -0
  25. package/dist/constitution/g2BehaviorPolicyMaterializer.js +241 -0
  26. package/dist/constitution/g2CandidateAttestation.js +179 -0
  27. package/dist/constitution/g2Candidates.js +195 -0
  28. package/dist/constitution/g2Drills.js +122 -0
  29. package/dist/constitution/g3.js +511 -0
  30. package/dist/constitution/g3Conformance.js +115 -0
  31. package/dist/constitution/lifecycle.js +189 -0
  32. package/dist/constitution/mutation.js +262 -0
  33. package/dist/constitution/nodeTestEvidence.js +47 -0
  34. package/dist/constitution/plan.js +172 -0
  35. package/dist/constitution/policyRuntime.js +8 -0
  36. package/dist/constitution/proof.js +166 -0
  37. package/dist/constitution/replay.js +361 -0
  38. package/dist/constitution/replayCache.js +89 -0
  39. package/dist/constitution/replayWorker.js +34 -0
  40. package/dist/constitution/repository.js +533 -0
  41. package/dist/constitution/schema.js +545 -0
  42. package/dist/constitution/scorecard.js +106 -0
  43. package/dist/constitution/service.js +1149 -0
  44. package/dist/constitution/shadow.js +235 -0
  45. package/dist/constitution/sourceMutation.js +316 -0
  46. package/dist/constitution/structural.js +601 -0
  47. package/dist/core/autoreview.js +27 -3
  48. package/dist/core/dupdetect.js +10 -3
  49. package/dist/core/events.js +61 -0
  50. package/dist/core/externalImports.js +24 -0
  51. package/dist/core/hookpolicy.js +3 -0
  52. package/dist/core/relativeImports.js +33 -0
  53. package/dist/core/stats.js +115 -0
  54. package/dist/extractors/git.js +81 -0
  55. package/dist/extractors/indexer.js +39 -38
  56. package/dist/extractors/nativeTreeSitter.js +108 -0
  57. package/dist/extractors/parse.js +5 -15
  58. package/dist/integrations/claudemd.js +8 -1
  59. package/dist/integrations/gitignore.js +8 -0
  60. package/dist/integrations/providers.js +32 -10
  61. package/dist/integrations/sync.js +16 -1
  62. package/dist/mcp/server.js +284 -0
  63. package/package.json +5 -1
@@ -0,0 +1,172 @@
1
+ import { basename } from "node:path";
2
+ import { shortHash } from "../core/ids.js";
3
+ import { firstCommitForFile, headSha, revExists, revParse } from "../extractors/git.js";
4
+ import { canonicalHash, policySemanticHash } from "./canonical.js";
5
+ import { policyCompositionBinding, policyProofHash } from "./composition.js";
6
+ import { graphSnapshot, mutationOperatorForPolicy, selectedPolicyForComposition } from "./evaluator.js";
7
+ import { createExecutableBehaviorProofPlan } from "./behaviorProof.js";
8
+ import { POLICY_EVALUATOR, MUTATION_ENGINE, ProofPlanSchema, } from "./schema.js";
9
+ function clamp(value, fallback, min, max) {
10
+ if (value == null || !Number.isFinite(value))
11
+ return fallback;
12
+ return Math.max(min, Math.min(max, Math.trunc(value)));
13
+ }
14
+ function hasBareNameSelector(policy) {
15
+ const assertion = policy.assertion;
16
+ if (assertion.kind === "executable-behavior")
17
+ return false;
18
+ const selectors = [assertion.subject, ...(assertion.kind === "exists" ? [] : [assertion.object]), ...(assertion.kind === "must-pass-through" ? [assertion.via] : [])];
19
+ return selectors.some(({ selector }) => selector.startsWith("symbol:") && !selector.slice("symbol:".length).includes(":"));
20
+ }
21
+ function relevantEvents(repository, policy, opts) {
22
+ const refs = new Set(policy.evidence.filter((ref) => ref.startsWith("ev_")));
23
+ return repository.listEvidence(opts)
24
+ .filter((event) => refs.has(event.id) || event.related_records.includes(policy.id))
25
+ .sort((a, b) => a.id.localeCompare(b.id));
26
+ }
27
+ function mergeFixtures(groups) {
28
+ const byCommit = new Map();
29
+ for (const fixture of groups.flat()) {
30
+ const existing = byCommit.get(fixture.ref);
31
+ if (existing && existing.expected !== fixture.expected) {
32
+ throw new Error(`fixture commit ${fixture.ref} has conflicting ${existing.expected}/${fixture.expected} expectations`);
33
+ }
34
+ if (!existing)
35
+ byCommit.set(fixture.ref, fixture);
36
+ }
37
+ return [...byCommit.values()].sort((a, b) => a.ref.localeCompare(b.ref) || a.label.localeCompare(b.label));
38
+ }
39
+ /** Deterministic compiler-to-harness contract. It plans replay and mutations but
40
+ * executes neither, grants no authority, and performs no provider/model call. */
41
+ export function createProofPlan(store, root, repository, policy, opts = {}) {
42
+ if (opts.publicOnly && opts.privateOnly)
43
+ throw new Error("choose only one of publicOnly or privateOnly");
44
+ if (policy.assertion.kind === "executable-behavior") {
45
+ if (opts.composition?.length)
46
+ throw new Error("executable-behavior policies cannot have exception composition");
47
+ return createExecutableBehaviorProofPlan(root, repository, policy, { now: opts.now, privateOnly: true });
48
+ }
49
+ const head = headSha(root);
50
+ if (!head)
51
+ throw new Error("proof planning needs a Git repository with a current HEAD");
52
+ const composition = opts.composition ?? [];
53
+ const parentHash = policySemanticHash(policy);
54
+ const policyHash = policyProofHash(policy, composition);
55
+ const compositionBinding = policyCompositionBinding(policy, composition);
56
+ const corpus = repository.getCorpus(policy.id, opts);
57
+ if (corpus) {
58
+ if (corpus.policy_hash !== parentHash) {
59
+ throw new Error(`proof corpus ${corpus.id} is stale for policy ${policy.id}; re-import it after the policy semantic change`);
60
+ }
61
+ if (corpus.repository !== basename(root) || corpus.data_class !== policy.data_class) {
62
+ throw new Error(`proof corpus ${corpus.id} does not match repository/data class for policy ${policy.id}`);
63
+ }
64
+ }
65
+ const events = relevantEvents(repository, policy, opts);
66
+ const sourceEvent = events.find((event) => !!event.commit);
67
+ const readDecision = (id) => opts.publicOnly
68
+ ? store.json.get("decisions", id)
69
+ : opts.privateOnly
70
+ ? store.getPrivateRec("decisions", id)
71
+ : store.getRec("decisions", id);
72
+ const decision = [...policy.legacy_refs, ...policy.evidence]
73
+ .filter((ref) => ref.startsWith("dec_"))
74
+ .map(readDecision)
75
+ .find((record) => !!record);
76
+ const policyCommit = firstCommitForFile(`.hunch/policies/${policy.id}.json`, root);
77
+ const sourceRef = sourceEvent?.commit ?? decision?.commit ?? (policyCommit || head);
78
+ if (!revExists(sourceRef, root))
79
+ throw new Error(`proof-plan source commit ${sourceRef} does not resolve in this repository`);
80
+ const sourceCommit = revParse(sourceRef, root);
81
+ const structural = events.find((event) => event.structural_delta && (event.kind === "bug_fix" || event.kind === "revert" || event.kind === "decision"));
82
+ const structuralKnownBad = structural?.structural_delta
83
+ ? [{
84
+ kind: "commit",
85
+ ref: structural.structural_delta.before_commit,
86
+ label: `first parent before linked ${structural.kind.replace("_", " ")}`,
87
+ expected: "violated",
88
+ }]
89
+ : [];
90
+ const knownBad = mergeFixtures([corpus?.known_bad ?? [], structuralKnownBad]);
91
+ const knownGood = mergeFixtures([
92
+ corpus?.known_good ?? [],
93
+ [{ kind: "commit", ref: head, label: "current accepted baseline", expected: "satisfied" }],
94
+ ]);
95
+ const attestedKnownGood = knownGood.filter((fixture) => !!fixture.attestation);
96
+ const maxCommits = clamp(opts.maxCommits, 20, 0, 500);
97
+ const maxMutations = clamp(opts.maxMutations, 3, 0, 100);
98
+ const mutationPolicy = composition.length
99
+ ? selectedPolicyForComposition(policy, composition, graphSnapshot(store, root, { publicOnly: opts.publicOnly }))
100
+ : policy;
101
+ const operator = mutationOperatorForPolicy(mutationPolicy);
102
+ const plannedMutations = [
103
+ { operator, base: head, expected: "violated", required: true },
104
+ { operator: "comment-string-control", base: head, expected: "satisfied", required: true },
105
+ {
106
+ operator: "same-name-ambiguity-control",
107
+ base: head,
108
+ expected: hasBareNameSelector(policy) ? "unknown" : "satisfied",
109
+ required: true,
110
+ },
111
+ ].slice(0, maxMutations);
112
+ const body = {
113
+ policy_id: policy.id,
114
+ policy_candidate_hash: policyHash,
115
+ repository: basename(root),
116
+ data_class: policy.data_class,
117
+ source_commit: sourceCommit,
118
+ valid_from_commit: sourceCommit,
119
+ evaluator: { ...POLICY_EVALUATOR },
120
+ mutation_engine: { ...MUTATION_ENGINE },
121
+ ...(compositionBinding ? { composition: compositionBinding } : {}),
122
+ ...(corpus ? { corpus_manifest: { id: corpus.id, content_hash: corpus.content_hash } } : {}),
123
+ corpus: {
124
+ current_baseline: { kind: "commit", ref: head, label: "current repository baseline", expected: "satisfied" },
125
+ accepted_history: {
126
+ from: sourceCommit,
127
+ to: head,
128
+ first_parent: true,
129
+ max_commits: maxCommits,
130
+ exclude: [...new Set([
131
+ ...knownBad.map((fixture) => fixture.ref),
132
+ ...attestedKnownGood.map((fixture) => fixture.ref),
133
+ ])].sort(),
134
+ },
135
+ known_bad: knownBad,
136
+ known_good: knownGood,
137
+ },
138
+ mutations: plannedMutations,
139
+ budgets: {
140
+ max_commits: maxCommits,
141
+ max_mutations: maxMutations,
142
+ max_minutes: clamp(opts.maxMinutes, 5, 1, 120),
143
+ },
144
+ expected: [
145
+ { leg: "current_baseline", result: "satisfied", classification_required: false },
146
+ ...(knownBad.length ? [{ leg: "known_bad", result: "violated", classification_required: false }] : []),
147
+ { leg: "known_good", result: "satisfied", classification_required: false },
148
+ { leg: "accepted_history", classification_required: true },
149
+ ...(maxMutations > 0 ? [{ leg: "mutations", result: "violated", classification_required: false }] : []),
150
+ ],
151
+ evidence_refs: [...new Set([...policy.evidence, ...events.map((event) => event.id)])].sort(),
152
+ limitations: [
153
+ "ProofPlan generation does not execute accepted-history replay or project tests.",
154
+ "Known-bad commits are included only when an attributable fix/revert delta identifies the first parent.",
155
+ ...(attestedKnownGood.length
156
+ ? ["Human-attested known-good fixtures are replayed as explicit corpus evidence and excluded from accepted-history sampling; attestation cannot waive a policy or grant authority."]
157
+ : []),
158
+ ...(compositionBinding
159
+ ? [`Plan binds the broad parent and ${compositionBinding.members.length} explicit scoped exception policy record(s) into one evaluator receipt.`]
160
+ : []),
161
+ ...policy.limitations,
162
+ ],
163
+ };
164
+ const contentHash = canonicalHash(body);
165
+ return ProofPlanSchema.parse({
166
+ id: `plan_${shortHash(contentHash)}`,
167
+ content_hash: contentHash,
168
+ ...body,
169
+ created_at: opts.now ?? new Date().toISOString(),
170
+ });
171
+ }
172
+ //# sourceMappingURL=plan.js.map
@@ -0,0 +1,8 @@
1
+ import { BEHAVIOR_MUTATION_ENGINE, BEHAVIOR_POLICY_EVALUATOR, MUTATION_ENGINE, POLICY_EVALUATOR, } from "./schema.js";
2
+ export function evaluatorForPolicy(policy) {
3
+ return policy.assertion.kind === "executable-behavior" ? BEHAVIOR_POLICY_EVALUATOR : POLICY_EVALUATOR;
4
+ }
5
+ export function mutationEngineForPolicy(policy) {
6
+ return policy.assertion.kind === "executable-behavior" ? BEHAVIOR_MUTATION_ENGINE : MUTATION_ENGINE;
7
+ }
8
+ //# sourceMappingURL=policyRuntime.js.map
@@ -0,0 +1,166 @@
1
+ import { canonicalHash, proofEvaluationHash, proofId } from "./canonical.js";
2
+ import { assertCompositionBinding, policyCompositionBinding, policyProofHash } from "./composition.js";
3
+ import { evaluateCompositePolicyOnSnapshot, evaluatePolicyOnSnapshot, graphSnapshot, mutationOperatorForPolicy, selectedPolicyForComposition } from "./evaluator.js";
4
+ import { runMutationHarness } from "./mutation.js";
5
+ import { replayProofPlan } from "./replay.js";
6
+ import { POLICY_EVALUATOR, MUTATION_ENGINE, PolicyProofSchema, } from "./schema.js";
7
+ import { proveExecutableBehaviorPolicy } from "./behaviorProof.js";
8
+ function summary(results) {
9
+ const count = (kind) => results.filter((r) => r.result === kind).length;
10
+ return {
11
+ total: results.length,
12
+ satisfied: count("satisfied"),
13
+ violated: count("violated"),
14
+ not_applicable: count("not_applicable"),
15
+ unknown: count("unknown"),
16
+ error: count("error"),
17
+ receipt_hashes: results.map((r) => r.deterministic_hash),
18
+ };
19
+ }
20
+ const emptySummary = () => ({
21
+ total: 0,
22
+ satisfied: 0,
23
+ violated: 0,
24
+ not_applicable: 0,
25
+ unknown: 0,
26
+ error: 0,
27
+ receipt_hashes: [],
28
+ });
29
+ function replaySummary(receipts) {
30
+ const count = (kind) => receipts.filter((receipt) => receipt.result === kind).length;
31
+ return {
32
+ total: receipts.length,
33
+ satisfied: count("satisfied"),
34
+ violated: count("violated"),
35
+ not_applicable: count("not_applicable"),
36
+ unknown: count("unknown"),
37
+ error: count("error"),
38
+ receipt_hashes: receipts.map((receipt) => receipt.deterministic_hash),
39
+ };
40
+ }
41
+ /** Inward proof execution. A canonical plan uses immutable disposable replay
42
+ * snapshots; the no-plan fallback preserves the original Gate-G1 current graph
43
+ * plus one deterministic mutation behavior. */
44
+ export function provePolicy(store, root, policy, opts = {}) {
45
+ if (policy.assertion.kind === "executable-behavior") {
46
+ if (!opts.plan)
47
+ throw new Error("executable-behavior proof requires an exact ProofPlan");
48
+ if (opts.composition?.length)
49
+ throw new Error("executable-behavior policies cannot have exception composition");
50
+ return proveExecutableBehaviorPolicy(root, policy, opts.plan, { now: opts.now });
51
+ }
52
+ if (opts.plan && (opts.plan.mutation_engine?.name !== MUTATION_ENGINE.name
53
+ || opts.plan.mutation_engine.version !== MUTATION_ENGINE.version)) {
54
+ throw new Error(`proof plan ${opts.plan.id} requires regeneration for mutation engine ${MUTATION_ENGINE.name}@${MUTATION_ENGINE.version}`);
55
+ }
56
+ const composition = opts.composition ?? [];
57
+ const compositionBinding = policyCompositionBinding(policy, composition);
58
+ if (opts.plan)
59
+ assertCompositionBinding(policy, composition, opts.plan.composition);
60
+ const evaluate = (snapshot) => composition.length
61
+ ? evaluateCompositePolicyOnSnapshot(policy, composition, snapshot)
62
+ : evaluatePolicyOnSnapshot(policy, snapshot);
63
+ const replay = opts.plan ? replayProofPlan(root, policy, opts.plan, { composition }) : undefined;
64
+ const snapshot = replay?.current_snapshot ?? graphSnapshot(store, root, opts);
65
+ const fallbackCurrent = replay ? undefined : evaluate(snapshot);
66
+ const mutationBase = replay?.current_snapshot ?? snapshot;
67
+ const mutationPolicy = composition.length ? selectedPolicyForComposition(policy, composition, mutationBase) : policy;
68
+ const plannedMutations = opts.plan?.mutations ?? [{
69
+ operator: mutationOperatorForPolicy(mutationPolicy),
70
+ base: mutationBase.head,
71
+ expected: "violated",
72
+ required: true,
73
+ }];
74
+ const policyHash = policyProofHash(policy, composition);
75
+ const mutationHarness = runMutationHarness(root, policy, mutationBase, plannedMutations, {
76
+ policyHash,
77
+ mutationPolicy,
78
+ evaluate,
79
+ });
80
+ const mutationSummary = summary(mutationHarness.primary_evaluations);
81
+ if (replay)
82
+ mutationSummary.receipt_hashes = mutationHarness.primary_evaluations.map(proofEvaluationHash);
83
+ const primaryMutationReceipts = mutationHarness.receipts.filter((receipt) => receipt.kind === "primary");
84
+ const controlReceipts = mutationHarness.receipts.filter((receipt) => receipt.kind === "control");
85
+ const currentSummary = replay ? replaySummary([replay.current]) : summary(fallbackCurrent ? [fallbackCurrent] : []);
86
+ const knownBadSummary = replay ? replaySummary(replay.known_bad) : emptySummary();
87
+ const knownGoodSummary = replay ? replaySummary(replay.known_good) : summary(fallbackCurrent?.result === "satisfied" ? [fallbackCurrent] : []);
88
+ const historySummary = replay ? replaySummary(replay.accepted_history) : emptySummary();
89
+ let proofClass = "P0";
90
+ const baselineSatisfied = currentSummary.satisfied === 1 && currentSummary.error === 0 && currentSummary.unknown === 0;
91
+ if (baselineSatisfied)
92
+ proofClass = "P1";
93
+ if (baselineSatisfied && replay?.history_complete)
94
+ proofClass = "P2";
95
+ const caughtKnownBad = replay?.known_bad.some((receipt) => receipt.expected === "violated" && receipt.result === "violated") ?? false;
96
+ const caughtMutation = primaryMutationReceipts.some((receipt) => receipt.passed && receipt.result === "violated");
97
+ if (baselineSatisfied && (caughtKnownBad || caughtMutation))
98
+ proofClass = "P3";
99
+ const fallbackPlan = {
100
+ policy_hash: policyHash,
101
+ evaluator: POLICY_EVALUATOR,
102
+ mutation_engine: MUTATION_ENGINE,
103
+ ...(compositionBinding ? { composition: compositionBinding } : {}),
104
+ current_graph: snapshot.graph_hash,
105
+ mutations: plannedMutations.map((mutation) => mutation.operator),
106
+ budgets: { max_commits: 1, max_mutations: 1, max_minutes: 1 },
107
+ };
108
+ const planHash = opts.plan?.content_hash ?? canonicalHash(fallbackPlan);
109
+ const id = proofId({ policy_hash: policyHash, plan_hash: planHash, evaluator: POLICY_EVALUATOR });
110
+ const now = opts.now ?? new Date().toISOString();
111
+ const historyHits = historySummary.violated;
112
+ const replayProblems = historySummary.error + historySummary.unknown;
113
+ return PolicyProofSchema.parse({
114
+ id,
115
+ plan_hash: planHash,
116
+ policy_hash: policyHash,
117
+ evaluator: { ...POLICY_EVALUATOR },
118
+ mutation_engine: { ...MUTATION_ENGINE },
119
+ ...(compositionBinding ? { composition: compositionBinding } : {}),
120
+ generated_at: now,
121
+ current: currentSummary,
122
+ known_bad: knownBadSummary,
123
+ known_good: knownGoodSummary,
124
+ accepted_history: { ...historySummary, classified_hits: [] },
125
+ mutations: {
126
+ ...mutationSummary,
127
+ operator_coverage: Object.fromEntries(primaryMutationReceipts.map((receipt) => [receipt.operator, receipt.passed ? 1 : 0])),
128
+ },
129
+ replay_receipts: replay?.replay_receipts ?? [],
130
+ mutation_receipts: mutationHarness.receipts,
131
+ mutation_controls: {
132
+ total: controlReceipts.length,
133
+ passed: controlReceipts.filter((receipt) => receipt.passed).length,
134
+ failed: controlReceipts.filter((receipt) => !receipt.passed).length,
135
+ receipt_hashes: controlReceipts.map((receipt) => receipt.deterministic_hash),
136
+ },
137
+ project_checks: { build: "not_run", test: "not_run", required_for_evaluator_sensitivity: false },
138
+ limitations: [
139
+ ...policy.limitations,
140
+ ...(replay ? [
141
+ "Replay uses the pinned static evaluator in disposable Git worktrees; project build/tests and repository code are never executed.",
142
+ replay.selected_history_commits.length
143
+ ? `Accepted-history replay evaluated ${replay.selected_history_commits.length} bounded first-parent commit(s).`
144
+ : "Accepted-history selector resolved to zero non-baseline commits.",
145
+ ...(historyHits ? [`Accepted-history contains ${historyHits} unclassified violation hit(s); no false-positive claim or blocking approval is allowed until classification.`] : []),
146
+ ...(replayProblems ? [`Accepted-history contains ${replayProblems} unknown/error result(s); they remain visible and prevent blocking approval.`] : []),
147
+ "Primary mutation applies to an immutable disposable source checkout and must remain parseable; comment/string and same-name controls are separate, while project build/test outcomes remain non-authoritative follow-on evidence.",
148
+ "Shadow outcomes are tracked as separate append-only measurements and never mutate this immutable proof.",
149
+ ...(compositionBinding ? [`Composite receipts bind ${compositionBinding.members.length} explicit scoped exception policy record(s) to their broad parent.`] : []),
150
+ ] : ["Gate G1 proof covers the current graph and one deterministic mutation; historical replay and shadow outcomes are not available without a ProofPlan."]),
151
+ ],
152
+ proof_class: proofClass,
153
+ artifact_hashes: {
154
+ policy: policyHash,
155
+ ...(opts.plan ? { plan: opts.plan.content_hash } : {}),
156
+ ...(compositionBinding ? { composition: compositionBinding.composite_hash } : {}),
157
+ ...(replay?.current.graph_hash ? { graph: replay.current.graph_hash } : { graph: snapshot.graph_hash }),
158
+ ...(currentSummary.receipt_hashes[0] ? { current_receipt: currentSummary.receipt_hashes[0] } : {}),
159
+ ...(replay ? { replay_manifest: canonicalHash(replay.replay_receipts) } : {}),
160
+ ...(primaryMutationReceipts[0] ? { mutation_receipt: primaryMutationReceipts[0].deterministic_hash } : {}),
161
+ ...(mutationHarness.receipts.length ? { mutation_manifest: canonicalHash(mutationHarness.receipts) } : {}),
162
+ },
163
+ data_class: policy.data_class,
164
+ });
165
+ }
166
+ //# sourceMappingURL=proof.js.map