@meetless/mla 0.1.4
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/LICENSE +201 -0
- package/README.md +81 -0
- package/dist/build-info.json +9 -0
- package/dist/bundles/ask-core.js +396 -0
- package/dist/bundles/mcp.js +16592 -0
- package/dist/bundles/trace-core.js +263 -0
- package/dist/cli.js +828 -0
- package/dist/commands/activate.js +781 -0
- package/dist/commands/adoption.js +130 -0
- package/dist/commands/ask.js +290 -0
- package/dist/commands/context.js +114 -0
- package/dist/commands/debug.js +313 -0
- package/dist/commands/doctor.js +1021 -0
- package/dist/commands/enrich.js +427 -0
- package/dist/commands/evidence.js +229 -0
- package/dist/commands/flush.js +184 -0
- package/dist/commands/graph.js +104 -0
- package/dist/commands/init.js +272 -0
- package/dist/commands/internal-active-review.js +322 -0
- package/dist/commands/internal-auto-index.js +188 -0
- package/dist/commands/internal-capture-decisions.js +320 -0
- package/dist/commands/internal-evidence-correlate.js +239 -0
- package/dist/commands/internal-evidence-hooks.js +240 -0
- package/dist/commands/internal-evidence-inject.js +231 -0
- package/dist/commands/internal-finalize.js +221 -0
- package/dist/commands/internal-pretool-observe.js +225 -0
- package/dist/commands/internal-refresh.js +136 -0
- package/dist/commands/internal-session-nudge.js +120 -0
- package/dist/commands/internal-steer-sync.js +117 -0
- package/dist/commands/internal-turn-recap.js +140 -0
- package/dist/commands/kb.js +375 -0
- package/dist/commands/kb_add.js +681 -0
- package/dist/commands/kb_forget.js +283 -0
- package/dist/commands/kb_move.js +45 -0
- package/dist/commands/kb_pending.js +410 -0
- package/dist/commands/kb_personal.js +149 -0
- package/dist/commands/kb_promote.js +188 -0
- package/dist/commands/kb_purge.js +168 -0
- package/dist/commands/kb_reingest.js +335 -0
- package/dist/commands/kb_retime.js +170 -0
- package/dist/commands/kb_review.js +391 -0
- package/dist/commands/kb_revision.js +179 -0
- package/dist/commands/kb_show.js +385 -0
- package/dist/commands/label.js +226 -0
- package/dist/commands/login.js +295 -0
- package/dist/commands/logout.js +108 -0
- package/dist/commands/mcp-supervisor.js +93 -0
- package/dist/commands/mcp.js +227 -0
- package/dist/commands/queue-prune.js +98 -0
- package/dist/commands/review.js +358 -0
- package/dist/commands/rewire.js +124 -0
- package/dist/commands/rules.js +728 -0
- package/dist/commands/scan-context.js +67 -0
- package/dist/commands/session.js +347 -0
- package/dist/commands/stats.js +479 -0
- package/dist/commands/status.js +61 -0
- package/dist/commands/summary.js +250 -0
- package/dist/commands/turn.js +114 -0
- package/dist/commands/uninstall.js +222 -0
- package/dist/commands/whoami.js +102 -0
- package/dist/commands/workspace.js +130 -0
- package/dist/hooks-template/ce0-post-tool-use.sh +34 -0
- package/dist/hooks-template/ce0-session-start.sh +49 -0
- package/dist/hooks-template/ce0-stop.sh +29 -0
- package/dist/hooks-template/ce0-user-prompt-submit.sh +38 -0
- package/dist/hooks-template/common.sh +934 -0
- package/dist/hooks-template/event-batch-filter.jq +67 -0
- package/dist/hooks-template/flush.sh +503 -0
- package/dist/hooks-template/post-tool-use.sh +423 -0
- package/dist/hooks-template/pre-tool-use.sh +69 -0
- package/dist/hooks-template/session-start.sh +140 -0
- package/dist/hooks-template/stop.sh +308 -0
- package/dist/hooks-template/user-prompt-submit.sh +1162 -0
- package/dist/lib/activation.js +79 -0
- package/dist/lib/active-conflict-cache.js +141 -0
- package/dist/lib/active-memory.js +59 -0
- package/dist/lib/active-review-runner.js +26 -0
- package/dist/lib/agent-decision/index.js +25 -0
- package/dist/lib/agent-decision/keys.js +49 -0
- package/dist/lib/agent-decision/normalize-claude.js +183 -0
- package/dist/lib/agent-decision/types.js +21 -0
- package/dist/lib/agent-decision/validate.js +216 -0
- package/dist/lib/analytics/capture.js +96 -0
- package/dist/lib/analytics/command-event.js +267 -0
- package/dist/lib/analytics/consent.js +58 -0
- package/dist/lib/analytics/coverage-gap.js +96 -0
- package/dist/lib/analytics/envelope.js +236 -0
- package/dist/lib/analytics/event-id.js +86 -0
- package/dist/lib/analytics/evidence.js +150 -0
- package/dist/lib/analytics/followthrough.js +194 -0
- package/dist/lib/analytics/forwarder.js +109 -0
- package/dist/lib/analytics/logs.js +78 -0
- package/dist/lib/analytics/metrics.js +78 -0
- package/dist/lib/analytics/recorder.js +92 -0
- package/dist/lib/analytics/review-analytics.js +75 -0
- package/dist/lib/analytics/sequence.js +77 -0
- package/dist/lib/analytics/store.js +131 -0
- package/dist/lib/analytics/turn-recap.js +279 -0
- package/dist/lib/artifact_id.js +108 -0
- package/dist/lib/auth-breaker.js +161 -0
- package/dist/lib/auto-index.js +112 -0
- package/dist/lib/classifier.js +88 -0
- package/dist/lib/config.js +298 -0
- package/dist/lib/conflict-advisory.js +64 -0
- package/dist/lib/debug-bundle.js +520 -0
- package/dist/lib/enrichment/ingest.js +301 -0
- package/dist/lib/enrichment/plan.js +253 -0
- package/dist/lib/enrichment/protocol.js +359 -0
- package/dist/lib/enrichment/scout-brief.js +176 -0
- package/dist/lib/failure-telemetry.js +444 -0
- package/dist/lib/git.js +200 -0
- package/dist/lib/governance-cache.js +77 -0
- package/dist/lib/governed-path-cache.js +76 -0
- package/dist/lib/http.js +677 -0
- package/dist/lib/identity-envelope.js +23 -0
- package/dist/lib/kb-candidate.js +65 -0
- package/dist/lib/kb_acl.js +98 -0
- package/dist/lib/login.js +353 -0
- package/dist/lib/mcp-fetchers.js +130 -0
- package/dist/lib/mcp-restart.js +47 -0
- package/dist/lib/observability.js +805 -0
- package/dist/lib/open-url.js +33 -0
- package/dist/lib/orphan-guard.js +70 -0
- package/dist/lib/packaged.js +21 -0
- package/dist/lib/reconcile-sessions.js +171 -0
- package/dist/lib/redactor.js +89 -0
- package/dist/lib/relationship-candidate-query.js +27 -0
- package/dist/lib/render.js +611 -0
- package/dist/lib/rules/applicability.js +64 -0
- package/dist/lib/rules/attest-code-rule-version.js +47 -0
- package/dist/lib/rules/attest-notes-location.js +217 -0
- package/dist/lib/rules/attest-rule-version.js +69 -0
- package/dist/lib/rules/canonical-json.js +97 -0
- package/dist/lib/rules/ce0-emit.js +64 -0
- package/dist/lib/rules/ce0-evidence.js +281 -0
- package/dist/lib/rules/ce0-recall-sample.js +82 -0
- package/dist/lib/rules/ce0-rule.js +55 -0
- package/dist/lib/rules/ce0-sampling-bucket.js +15 -0
- package/dist/lib/rules/ce0-store.js +683 -0
- package/dist/lib/rules/ce0-telemetry-project.js +93 -0
- package/dist/lib/rules/ce0-telemetry.js +158 -0
- package/dist/lib/rules/code-rule-registry.js +17 -0
- package/dist/lib/rules/command-match.js +185 -0
- package/dist/lib/rules/consult-evidence-binding.js +27 -0
- package/dist/lib/rules/consultation-capture-adapter.js +193 -0
- package/dist/lib/rules/content-match.js +56 -0
- package/dist/lib/rules/deny-admission.js +99 -0
- package/dist/lib/rules/durable-observation.js +190 -0
- package/dist/lib/rules/enforce-notes-version.js +421 -0
- package/dist/lib/rules/evaluation-input-hash.js +126 -0
- package/dist/lib/rules/evaluator.js +108 -0
- package/dist/lib/rules/inert-rule-families.js +51 -0
- package/dist/lib/rules/input-authority-resolver.js +241 -0
- package/dist/lib/rules/interception-schema.js +170 -0
- package/dist/lib/rules/interception-store.js +267 -0
- package/dist/lib/rules/live-input-authority.js +66 -0
- package/dist/lib/rules/local-matcher.js +108 -0
- package/dist/lib/rules/local-observe.js +79 -0
- package/dist/lib/rules/local-rule-version-repo.js +214 -0
- package/dist/lib/rules/memory-requirement.js +109 -0
- package/dist/lib/rules/notes-observe.js +39 -0
- package/dist/lib/rules/notes-path.js +261 -0
- package/dist/lib/rules/notes-rule.js +75 -0
- package/dist/lib/rules/observe-adapter.js +114 -0
- package/dist/lib/rules/observed-rule-hash.js +119 -0
- package/dist/lib/rules/prompt-submit-adapter.js +132 -0
- package/dist/lib/rules/requirement-subject.js +240 -0
- package/dist/lib/rules/rule-activity.js +67 -0
- package/dist/lib/rules/rule-version-hash.js +151 -0
- package/dist/lib/rules/runtime-scope.js +55 -0
- package/dist/lib/rules/stop-adapter.js +116 -0
- package/dist/lib/rules/stop-response-snapshot.js +174 -0
- package/dist/lib/rules/types.js +10 -0
- package/dist/lib/rules/ulid.js +46 -0
- package/dist/lib/rules/version-evaluation.js +156 -0
- package/dist/lib/scanner/agent-memory.js +99 -0
- package/dist/lib/scanner/bootstrap-summary.js +87 -0
- package/dist/lib/scanner/cache.js +59 -0
- package/dist/lib/scanner/frontmatter.js +42 -0
- package/dist/lib/scanner/parse-directives.js +69 -0
- package/dist/lib/scanner/parse-structured.js +72 -0
- package/dist/lib/scanner/render.js +73 -0
- package/dist/lib/scanner/scan.js +132 -0
- package/dist/lib/scanner/score.js +38 -0
- package/dist/lib/scanner/scout-mission.js +126 -0
- package/dist/lib/scanner/types.js +7 -0
- package/dist/lib/session-scope.js +195 -0
- package/dist/lib/spool.js +355 -0
- package/dist/lib/staleness.js +100 -0
- package/dist/lib/steer-cache.js +87 -0
- package/dist/lib/tagged-reference.js +20 -0
- package/dist/lib/temporal.js +109 -0
- package/dist/lib/turn-recap-emit.js +67 -0
- package/dist/lib/unwire.js +253 -0
- package/dist/lib/update-check.js +469 -0
- package/dist/lib/update-notifier.js +217 -0
- package/dist/lib/upgrade-apply.js +643 -0
- package/dist/lib/wire.js +1087 -0
- package/dist/lib/workspace.js +96 -0
- package/dist/lib/zip.js +154 -0
- package/dist/pretool-entry.js +37 -0
- package/package.json +75 -0
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Coverage-gap classification (spec §7.5, INV-COVERAGE-GAP-1).
|
|
3
|
+
//
|
|
4
|
+
// A zero-result or low-confidence retrieval is the most actionable forward
|
|
5
|
+
// signal mla produces, but ONLY if it distinguishes cause. "Capture more docs"
|
|
6
|
+
// is the wrong fix when the real problem is ranking, staleness, or a permission
|
|
7
|
+
// filter. This module is the single, pure classifier that maps the inject-time
|
|
8
|
+
// retrieval signals to one closed `coverage_gap_type`, so the inject command and
|
|
9
|
+
// its test run the identical code with no I/O.
|
|
10
|
+
//
|
|
11
|
+
// The classification is INJECT-TIME: it answers "why did this retrieval fail to
|
|
12
|
+
// help" from what we knew when we surfaced (or failed to surface) evidence. The
|
|
13
|
+
// seventh type, `candidates_found_not_used`, is OUTCOME-time (the agent had
|
|
14
|
+
// usable candidates but referenced none) and is owned by the correlator, never
|
|
15
|
+
// emitted here.
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.classifyCoverageGap = classifyCoverageGap;
|
|
18
|
+
exports.coerceTopicCategory = coerceTopicCategory;
|
|
19
|
+
exports.coerceRetrievalConfidence = coerceRetrievalConfidence;
|
|
20
|
+
exports.coverageGapEventId = coverageGapEventId;
|
|
21
|
+
exports.coverageGapNotUsedEventId = coverageGapNotUsedEventId;
|
|
22
|
+
exports.buildCoverageGapPayload = buildCoverageGapPayload;
|
|
23
|
+
const envelope_1 = require("./envelope");
|
|
24
|
+
const event_id_1 = require("./event-id");
|
|
25
|
+
// classifyCoverageGap returns the single canonical gap type, or null when there
|
|
26
|
+
// is no coverage gap to report (a healthy, confident retrieval). Precedence is
|
|
27
|
+
// most-specific cause first, so a single inject is attributed to exactly one
|
|
28
|
+
// type even when several signals are set (INV-COVERAGE-GAP-1):
|
|
29
|
+
//
|
|
30
|
+
// retrieval_error a bug shadows every other reading
|
|
31
|
+
// permission_filtered an ACL drop is an access problem, not knowledge
|
|
32
|
+
// no_candidate_found nothing came back at all
|
|
33
|
+
// stale_or_conflicting candidates exist but the KB needs reconciling
|
|
34
|
+
// low_confidence_candidates candidates exist but ranking is weak
|
|
35
|
+
// (null) confident, non-empty retrieval: no gap
|
|
36
|
+
//
|
|
37
|
+
// candidates_found_not_used is deliberately NOT reachable here: it is the
|
|
38
|
+
// outcome-time type the correlator emits when usable candidates were ignored.
|
|
39
|
+
function classifyCoverageGap(signals) {
|
|
40
|
+
if (signals.retrievalError)
|
|
41
|
+
return "retrieval_error";
|
|
42
|
+
if (signals.permissionFiltered)
|
|
43
|
+
return "permission_filtered";
|
|
44
|
+
if (signals.zeroResults)
|
|
45
|
+
return "no_candidate_found";
|
|
46
|
+
if (signals.staleOrConflicting)
|
|
47
|
+
return "stale_or_conflicting_candidates";
|
|
48
|
+
if (signals.retrievalConfidence === "low")
|
|
49
|
+
return "low_confidence_candidates";
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
// Coerce a free-form topic string to the closed query_topic_category enum,
|
|
53
|
+
// defaulting to "unknown" so an unrecognized topic never leaks a raw string
|
|
54
|
+
// past the PII boundary (INV-POSTHOG-PII-1).
|
|
55
|
+
function coerceTopicCategory(raw) {
|
|
56
|
+
if (raw && envelope_1.QUERY_TOPIC_CATEGORIES.includes(raw)) {
|
|
57
|
+
return raw;
|
|
58
|
+
}
|
|
59
|
+
return "unknown";
|
|
60
|
+
}
|
|
61
|
+
// Coerce a free-form confidence string to the closed enum, defaulting to "low"
|
|
62
|
+
// (the same conservative default buildInjectPayload uses) so an unknown
|
|
63
|
+
// confidence never inflates the dashboard.
|
|
64
|
+
function coerceRetrievalConfidence(raw) {
|
|
65
|
+
if (raw && envelope_1.RETRIEVAL_CONFIDENCES.includes(raw)) {
|
|
66
|
+
return raw;
|
|
67
|
+
}
|
|
68
|
+
return "low";
|
|
69
|
+
}
|
|
70
|
+
// Deterministic event_id for an inject-time coverage gap. One inject produces at
|
|
71
|
+
// most one inject-time gap, so the inject_id IS the natural business key; the
|
|
72
|
+
// `coverage_gap:` prefix keeps it from colliding with the inject event's own id
|
|
73
|
+
// (which is the bare inject_id) under control's (workspace_id, event_id) dedupe.
|
|
74
|
+
function coverageGapEventId(injectId) {
|
|
75
|
+
return (0, event_id_1.deterministicEventId)(`coverage_gap:${injectId}`, 1);
|
|
76
|
+
}
|
|
77
|
+
// Deterministic event_id for the OUTCOME-time `candidates_found_not_used` gap the
|
|
78
|
+
// correlator emits when a confident, non-empty inject closed as ignored. A
|
|
79
|
+
// distinct business-key prefix from the inject-time gap so a single inject can
|
|
80
|
+
// carry both an inject-time gap and (in principle) an outcome-time gap without an
|
|
81
|
+
// event_id collision; in practice they are mutually exclusive (the correlator
|
|
82
|
+
// only emits this when no inject-time gap exists).
|
|
83
|
+
function coverageGapNotUsedEventId(injectId) {
|
|
84
|
+
return (0, event_id_1.deterministicEventId)(`coverage_gap_not_used:${injectId}`, 1);
|
|
85
|
+
}
|
|
86
|
+
// Build the typed, PII-bounded coverage-gap payload. ids/counts/enums/booleans
|
|
87
|
+
// only (no raw query text or paths): the raw topic stays in Langfuse.
|
|
88
|
+
function buildCoverageGapPayload(input) {
|
|
89
|
+
return {
|
|
90
|
+
inject_id: input.injectId,
|
|
91
|
+
coverage_gap_type: input.coverageGapType,
|
|
92
|
+
query_topic_category: input.queryTopicCategory,
|
|
93
|
+
retrieval_confidence: input.retrievalConfidence,
|
|
94
|
+
zero_results: input.zeroResults,
|
|
95
|
+
};
|
|
96
|
+
}
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// The analytics event envelope + closed enums + the typed event union.
|
|
3
|
+
//
|
|
4
|
+
// Spec section 6 (the event catalog) and section 10 (the implementation
|
|
5
|
+
// contract). Every remotely emitted event carries the envelope (INV-JOIN-1);
|
|
6
|
+
// every payload is ids/counts/rates/enums/booleans/durations only, never raw
|
|
7
|
+
// text/paths/argv/queries/errors (INV-POSTHOG-PII-1). Events are FLAT: the
|
|
8
|
+
// envelope fields and the payload fields sit at the same top level (matching
|
|
9
|
+
// the local jsonl examples in section 7.4).
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.CE0_HOOKS = exports.OBLIGATION_OUTCOME_LABELS = exports.CONSULTATION_RESULTS = exports.CONSULTATION_EXECUTIONS = exports.MEMORY_REQUIREMENTS = exports.REVIEW_DECISIONS = exports.RELATION_EDGE_TYPES = exports.COMMAND_SCOPES = exports.RETRIEVAL_CONFIDENCES = exports.INJECT_OUTCOMES = exports.WINDOW_CLOSED_REASONS = exports.COVERAGE_GAP_TYPES = exports.QUERY_TOPIC_CATEGORIES = exports.GOVERNED_RELATION_TYPES = exports.TOUCHED_SURFACES = exports.COMMAND_OUTCOMES = exports.SOURCE_SURFACES = exports.EVENT_SOURCES = exports.EVENT_TYPES = exports.SCHEMA_VERSION = void 0;
|
|
12
|
+
exports.makeEnvelope = makeEnvelope;
|
|
13
|
+
exports.buildAttribution = buildAttribution;
|
|
14
|
+
exports.envelopeMissingKeys = envelopeMissingKeys;
|
|
15
|
+
exports.assertEnvelopeComplete = assertEnvelopeComplete;
|
|
16
|
+
exports.isRemotelyEmittable = isRemotelyEmittable;
|
|
17
|
+
// INV-SCHEMA-1: every payload carries schema_version and is forward-compatible.
|
|
18
|
+
exports.SCHEMA_VERSION = 1;
|
|
19
|
+
// --- closed enums (section 6.3) ---------------------------------------------
|
|
20
|
+
// As const tuples so membership can be validated at the privacy boundary; no
|
|
21
|
+
// open string ever reaches PostHog.
|
|
22
|
+
exports.EVENT_TYPES = [
|
|
23
|
+
"mla_command",
|
|
24
|
+
"mla_evidence_inject",
|
|
25
|
+
"mla_evidence_outcome",
|
|
26
|
+
"mla_coverage_gap",
|
|
27
|
+
"mla_contradiction",
|
|
28
|
+
"mla_review_decision",
|
|
29
|
+
"mla_stats_viewed",
|
|
30
|
+
// CE0 evidence-consultation telemetry (§6.4). Named per the ratified proposal
|
|
31
|
+
// contract (no `mla_` prefix): these four are the PostHog projection of the
|
|
32
|
+
// obligation lifecycle and the dashboards in §6.4 query them by these names.
|
|
33
|
+
"memory_requirement_assessed",
|
|
34
|
+
"evidence_consultation_completed",
|
|
35
|
+
"evidence_obligation_finalized",
|
|
36
|
+
"evidence_hook_health",
|
|
37
|
+
];
|
|
38
|
+
exports.EVENT_SOURCES = ["cli", "hook", "mcp", "control", "intel"];
|
|
39
|
+
// The emission-surface label carried in the attribution block (spec section 3.7
|
|
40
|
+
// / T1.10). Derived from the typed `source` enum, NOT a free string, so the two
|
|
41
|
+
// axes can never drift: `source` is the closed emission channel (cli|hook|mcp),
|
|
42
|
+
// `sourceSurface` is its human-facing uppercase form. Kept distinct from the
|
|
43
|
+
// product-origin axis (`source:"mla"`), which is a constant on every event.
|
|
44
|
+
exports.SOURCE_SURFACES = {
|
|
45
|
+
cli: "CLI",
|
|
46
|
+
hook: "HOOK",
|
|
47
|
+
mcp: "MCP",
|
|
48
|
+
control: "CONTROL",
|
|
49
|
+
intel: "INTEL",
|
|
50
|
+
};
|
|
51
|
+
exports.COMMAND_OUTCOMES = [
|
|
52
|
+
"success",
|
|
53
|
+
"user_error",
|
|
54
|
+
"system_error",
|
|
55
|
+
"auth_error",
|
|
56
|
+
"network_error",
|
|
57
|
+
"permission_denied",
|
|
58
|
+
"validation_error",
|
|
59
|
+
"noop",
|
|
60
|
+
"cancelled",
|
|
61
|
+
"timeout",
|
|
62
|
+
];
|
|
63
|
+
exports.TOUCHED_SURFACES = [
|
|
64
|
+
"code",
|
|
65
|
+
"tests",
|
|
66
|
+
"docs",
|
|
67
|
+
"config",
|
|
68
|
+
"migration",
|
|
69
|
+
"infra",
|
|
70
|
+
"unknown",
|
|
71
|
+
];
|
|
72
|
+
exports.GOVERNED_RELATION_TYPES = [
|
|
73
|
+
"architecture",
|
|
74
|
+
"api_contract",
|
|
75
|
+
"migration",
|
|
76
|
+
"security",
|
|
77
|
+
"product_decision",
|
|
78
|
+
"data_model",
|
|
79
|
+
"unknown",
|
|
80
|
+
];
|
|
81
|
+
exports.QUERY_TOPIC_CATEGORIES = [
|
|
82
|
+
"architecture",
|
|
83
|
+
"testing",
|
|
84
|
+
"deployment",
|
|
85
|
+
"product_decision",
|
|
86
|
+
"customer_context",
|
|
87
|
+
"security",
|
|
88
|
+
"data_model",
|
|
89
|
+
"api_contract",
|
|
90
|
+
"migration",
|
|
91
|
+
"process",
|
|
92
|
+
"unknown",
|
|
93
|
+
];
|
|
94
|
+
exports.COVERAGE_GAP_TYPES = [
|
|
95
|
+
"no_candidate_found",
|
|
96
|
+
"low_confidence_candidates",
|
|
97
|
+
"candidates_found_not_used",
|
|
98
|
+
"stale_or_conflicting_candidates",
|
|
99
|
+
"retrieval_error",
|
|
100
|
+
"permission_filtered",
|
|
101
|
+
];
|
|
102
|
+
exports.WINDOW_CLOSED_REASONS = ["turn_limit", "time_limit", "still_open"];
|
|
103
|
+
exports.INJECT_OUTCOMES = ["used", "ignored", "unknown", "pending"];
|
|
104
|
+
exports.RETRIEVAL_CONFIDENCES = ["high", "medium", "low"];
|
|
105
|
+
// Command scope: where the command's effect landed. local = no backend hop;
|
|
106
|
+
// workspace = a single-workspace remote op; global = cross-workspace. Used by
|
|
107
|
+
// mla_command and mla_stats_viewed.
|
|
108
|
+
exports.COMMAND_SCOPES = ["local", "workspace", "global", "unknown"];
|
|
109
|
+
// The relationship edge classes mla curates (kb review / contradiction). These
|
|
110
|
+
// are the governed-relation lifecycle types, not the PII enums above.
|
|
111
|
+
exports.RELATION_EDGE_TYPES = [
|
|
112
|
+
"CONTRADICTS",
|
|
113
|
+
"SUPERSEDES",
|
|
114
|
+
"STALE_RELIES_ON",
|
|
115
|
+
"REFINES",
|
|
116
|
+
"unknown",
|
|
117
|
+
];
|
|
118
|
+
exports.REVIEW_DECISIONS = ["accept", "reject", "reclassify", "no_relation"];
|
|
119
|
+
// --- CE0 evidence-consultation telemetry enums (§6.4) -----------------------
|
|
120
|
+
// The wire forms of the rules-layer CE0 enums. Re-declared here, in the analytics
|
|
121
|
+
// layer, on purpose: the privacy boundary validates membership against THESE closed
|
|
122
|
+
// tuples, and the analytics layer must not depend up into lib/rules. The string
|
|
123
|
+
// values mirror the rules-layer unions (MemoryRequirement, ConsultationExecution,
|
|
124
|
+
// ObligationOutcome); ce0-telemetry.ts is the seam that maps one onto the other.
|
|
125
|
+
exports.MEMORY_REQUIREMENTS = ["REQUIRED", "NOT_REQUIRED", "UNKNOWN"];
|
|
126
|
+
exports.CONSULTATION_EXECUTIONS = ["COMPLETE", "FAILED", "UNKNOWN"];
|
|
127
|
+
exports.CONSULTATION_RESULTS = ["RESULTS_RETURNED", "NO_MATCH"];
|
|
128
|
+
exports.OBLIGATION_OUTCOME_LABELS = [
|
|
129
|
+
"NOT_DUE",
|
|
130
|
+
"COMPLIANT_ON_TIME",
|
|
131
|
+
"CONSULTED_LATE_WITH_EVIDENCE",
|
|
132
|
+
"CONSULTED_LATE_NO_EVIDENCE",
|
|
133
|
+
"MISSED",
|
|
134
|
+
"UNKNOWN",
|
|
135
|
+
"CANCELLED",
|
|
136
|
+
];
|
|
137
|
+
exports.CE0_HOOKS = [
|
|
138
|
+
"USER_PROMPT_SUBMIT",
|
|
139
|
+
"CONSULTATION_CAPTURE",
|
|
140
|
+
"STOP",
|
|
141
|
+
"OFFLINE_LABEL_IMPORT",
|
|
142
|
+
];
|
|
143
|
+
function makeEnvelope(input) {
|
|
144
|
+
const source = input.source ?? "cli";
|
|
145
|
+
return {
|
|
146
|
+
schema_version: exports.SCHEMA_VERSION,
|
|
147
|
+
event_id: input.event_id,
|
|
148
|
+
event_type: input.event_type,
|
|
149
|
+
created_at: input.created_at,
|
|
150
|
+
emitted_at: input.emitted_at ?? input.created_at,
|
|
151
|
+
workspace_id: input.workspace_id,
|
|
152
|
+
distinct_id: input.distinct_id,
|
|
153
|
+
session_id: input.session_id,
|
|
154
|
+
run_id: input.run_id,
|
|
155
|
+
trace_id: input.trace_id,
|
|
156
|
+
source,
|
|
157
|
+
attribution: buildAttribution({
|
|
158
|
+
source,
|
|
159
|
+
workspaceId: input.workspace_id,
|
|
160
|
+
actorWorkspaceUserId: input.actor_workspace_user_id ?? null,
|
|
161
|
+
agentSessionId: input.session_id,
|
|
162
|
+
repoFingerprint: input.repo_fingerprint ?? null,
|
|
163
|
+
}),
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
// Assemble the attribution block (T1.10). Pure: every field is mapped from a
|
|
167
|
+
// caller-supplied id/constant, no I/O. sourceSurface is derived from the closed
|
|
168
|
+
// `source` enum so it can never carry an open string; the `?? "CLI"` is a
|
|
169
|
+
// defensive default for the (type-impossible) case of an unmapped source.
|
|
170
|
+
function buildAttribution(input) {
|
|
171
|
+
return {
|
|
172
|
+
source: "mla",
|
|
173
|
+
sourceProduct: "MLA",
|
|
174
|
+
sourceSurface: exports.SOURCE_SURFACES[input.source] ?? "CLI",
|
|
175
|
+
actorWorkspaceUserId: input.actorWorkspaceUserId,
|
|
176
|
+
workspaceId: input.workspaceId,
|
|
177
|
+
agentSessionId: input.agentSessionId,
|
|
178
|
+
repoFingerprint: input.repoFingerprint,
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
// --- validators (INV-JOIN-1, the test contract) -----------------------------
|
|
182
|
+
// The eight join fields the test contract requires on every event. workspace_id
|
|
183
|
+
// and session_id are allowed to be null here (an unbound local run); presence of
|
|
184
|
+
// the KEY is asserted, while remote-emittability (non-null workspace+session) is
|
|
185
|
+
// a separate, stricter check (isRemotelyEmittable).
|
|
186
|
+
const REQUIRED_ENVELOPE_KEYS = [
|
|
187
|
+
"schema_version",
|
|
188
|
+
"event_id",
|
|
189
|
+
"event_type",
|
|
190
|
+
"created_at",
|
|
191
|
+
"workspace_id",
|
|
192
|
+
"session_id",
|
|
193
|
+
"run_id",
|
|
194
|
+
"trace_id",
|
|
195
|
+
];
|
|
196
|
+
function envelopeMissingKeys(ev) {
|
|
197
|
+
const missing = [];
|
|
198
|
+
for (const k of REQUIRED_ENVELOPE_KEYS) {
|
|
199
|
+
if (!(k in ev)) {
|
|
200
|
+
missing.push(k);
|
|
201
|
+
continue;
|
|
202
|
+
}
|
|
203
|
+
const v = ev[k];
|
|
204
|
+
// null is allowed for workspace_id / session_id (unbound run); undefined
|
|
205
|
+
// never is. Every other required key must be a non-empty value.
|
|
206
|
+
if (v === undefined) {
|
|
207
|
+
missing.push(k);
|
|
208
|
+
}
|
|
209
|
+
else if (v === null && k !== "workspace_id" && k !== "session_id") {
|
|
210
|
+
missing.push(k);
|
|
211
|
+
}
|
|
212
|
+
else if (typeof v === "string" && v.length === 0) {
|
|
213
|
+
missing.push(k);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
return missing;
|
|
217
|
+
}
|
|
218
|
+
// Throws if any required envelope field is missing. Used as the assertion in
|
|
219
|
+
// the envelope test (INV-JOIN-1) and as a defensive gate before remote ship.
|
|
220
|
+
function assertEnvelopeComplete(ev) {
|
|
221
|
+
const missing = envelopeMissingKeys(ev);
|
|
222
|
+
if (missing.length > 0) {
|
|
223
|
+
throw new Error(`analytics event missing required envelope field(s): ${missing.join(", ")}`);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
// INV-JOIN-1 applies to REMOTELY emitted events: they need a real workspace and
|
|
227
|
+
// session to join. An event with a null workspace_id or session_id is recorded
|
|
228
|
+
// locally (the operator's own view) but never shipped. The forwarder filters on
|
|
229
|
+
// this.
|
|
230
|
+
function isRemotelyEmittable(ev) {
|
|
231
|
+
return (envelopeMissingKeys(ev).length === 0 &&
|
|
232
|
+
typeof ev.workspace_id === "string" &&
|
|
233
|
+
ev.workspace_id.length > 0 &&
|
|
234
|
+
typeof ev.session_id === "string" &&
|
|
235
|
+
ev.session_id.length > 0);
|
|
236
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Event identity (spec section 10.2, INV-IDEMPOTENCY-1, INV-REMOTE-DEDUPE-1).
|
|
3
|
+
//
|
|
4
|
+
// Two minting strategies, picked by who is the system of record for the event:
|
|
5
|
+
//
|
|
6
|
+
// - CLI-ORIGIN events (mla_command, mla_evidence_inject): the CLI is the only
|
|
7
|
+
// writer, the event is produced exactly once, and a re-ship must reuse the
|
|
8
|
+
// SAME id. So we mint a UUID once and persist it in the local jsonl; every
|
|
9
|
+
// later forward reads it back. We do NOT content-hash these: identical
|
|
10
|
+
// commands at the same second would collide, and any serialization change
|
|
11
|
+
// would silently drift the id.
|
|
12
|
+
//
|
|
13
|
+
// - SERVER-RECOMPUTABLE events (mla_evidence_outcome, mla_review_decision):
|
|
14
|
+
// these are derived from a business key plus a monotonic version, and may be
|
|
15
|
+
// recomputed by more than one writer (the correlator, a backfill). A
|
|
16
|
+
// deterministic id makes that idempotent: sha256(businessKey + ":" + version).
|
|
17
|
+
//
|
|
18
|
+
// Control dedupes on the PAIR (workspace_id, event_id), so a deterministic id
|
|
19
|
+
// scoped only by business key never collides across workspaces.
|
|
20
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
21
|
+
if (k2 === undefined) k2 = k;
|
|
22
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
23
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
24
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
25
|
+
}
|
|
26
|
+
Object.defineProperty(o, k2, desc);
|
|
27
|
+
}) : (function(o, m, k, k2) {
|
|
28
|
+
if (k2 === undefined) k2 = k;
|
|
29
|
+
o[k2] = m[k];
|
|
30
|
+
}));
|
|
31
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
32
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
33
|
+
}) : function(o, v) {
|
|
34
|
+
o["default"] = v;
|
|
35
|
+
});
|
|
36
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
37
|
+
var ownKeys = function(o) {
|
|
38
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
39
|
+
var ar = [];
|
|
40
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
41
|
+
return ar;
|
|
42
|
+
};
|
|
43
|
+
return ownKeys(o);
|
|
44
|
+
};
|
|
45
|
+
return function (mod) {
|
|
46
|
+
if (mod && mod.__esModule) return mod;
|
|
47
|
+
var result = {};
|
|
48
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
49
|
+
__setModuleDefault(result, mod);
|
|
50
|
+
return result;
|
|
51
|
+
};
|
|
52
|
+
})();
|
|
53
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
54
|
+
exports.mintEventId = mintEventId;
|
|
55
|
+
exports.deterministicEventId = deterministicEventId;
|
|
56
|
+
exports.outcomeEventId = outcomeEventId;
|
|
57
|
+
exports.reviewDecisionEventId = reviewDecisionEventId;
|
|
58
|
+
const crypto = __importStar(require("crypto"));
|
|
59
|
+
// Mint a fresh, persisted-once id for a CLI-origin event. uuid (not a hash) so
|
|
60
|
+
// two structurally identical events are still distinct, and so the id is stable
|
|
61
|
+
// across re-serialization.
|
|
62
|
+
function mintEventId() {
|
|
63
|
+
return crypto.randomUUID();
|
|
64
|
+
}
|
|
65
|
+
// Deterministic id for a server-recomputable event. businessKey is the stable
|
|
66
|
+
// natural key (e.g. an inject_id or decision_id); version is a monotonically
|
|
67
|
+
// increasing integer so a corrected recomputation produces a NEW id rather than
|
|
68
|
+
// silently overwriting the prior landing. The ":" separator is unambiguous
|
|
69
|
+
// because neither side contains it (ids are uuids/hex, version is an integer).
|
|
70
|
+
function deterministicEventId(businessKey, version) {
|
|
71
|
+
if (!businessKey) {
|
|
72
|
+
throw new Error("deterministicEventId requires a non-empty businessKey");
|
|
73
|
+
}
|
|
74
|
+
if (!Number.isInteger(version) || version < 0) {
|
|
75
|
+
throw new Error(`deterministicEventId requires a non-negative integer version, got ${version}`);
|
|
76
|
+
}
|
|
77
|
+
return crypto.createHash("sha256").update(`${businessKey}:${version}`).digest("hex");
|
|
78
|
+
}
|
|
79
|
+
// Convenience wrappers naming the two server-recomputable event families, so
|
|
80
|
+
// callers can't accidentally pass the wrong version field.
|
|
81
|
+
function outcomeEventId(injectId, outcomeVersion) {
|
|
82
|
+
return deterministicEventId(injectId, outcomeVersion);
|
|
83
|
+
}
|
|
84
|
+
function reviewDecisionEventId(decisionId, decisionVersion) {
|
|
85
|
+
return deterministicEventId(decisionId, decisionVersion);
|
|
86
|
+
}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// The evidence-grounding lifecycle: build an inject payload at surface time, and
|
|
3
|
+
// derive its outcome once the correlation window closes. Both are pure functions
|
|
4
|
+
// over data the caller supplies, so the Stop-hook correlator and its test run the
|
|
5
|
+
// identical code with no I/O or clock baked in.
|
|
6
|
+
//
|
|
7
|
+
// The window is "next 3 turns OR 15 minutes, whichever first" (spec §0, §7.4).
|
|
8
|
+
// The inject is written immediately and counted as outcome=pending; the local
|
|
9
|
+
// correlator (v1: the Stop hook, INV-CORRELATOR-1) calls deriveOutcome to close
|
|
10
|
+
// eligible windows and append mla_evidence_outcome. Server-side correlation may
|
|
11
|
+
// validate or enrich, never be the only writer.
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.OUTCOME_VERSION = exports.WINDOW_MS = exports.WINDOW_TURNS = void 0;
|
|
14
|
+
exports.buildInjectPayload = buildInjectPayload;
|
|
15
|
+
exports.deriveOutcome = deriveOutcome;
|
|
16
|
+
const envelope_1 = require("./envelope");
|
|
17
|
+
const event_id_1 = require("./event-id");
|
|
18
|
+
const followthrough_1 = require("./followthrough");
|
|
19
|
+
// The turn window covers the inject turn and its next 3 turns; the wall-clock
|
|
20
|
+
// window is 15 minutes. Whichever fills first closes the inject (§0).
|
|
21
|
+
exports.WINDOW_TURNS = 3;
|
|
22
|
+
exports.WINDOW_MS = 15 * 60 * 1000;
|
|
23
|
+
// The current outcome schema generation. Bumped only when the outcome derivation
|
|
24
|
+
// changes meaning, so a recomputed outcome gets a NEW deterministic event_id
|
|
25
|
+
// rather than silently overwriting the prior landing (event-id.ts).
|
|
26
|
+
exports.OUTCOME_VERSION = 1;
|
|
27
|
+
// buildInjectPayload normalizes the hook's raw retrieval result into the typed,
|
|
28
|
+
// PII-bounded inject payload. It mints the inject_id ONCE (CLI-origin identity,
|
|
29
|
+
// §10.2) and stamps the window deadline from the supplied clock so the function
|
|
30
|
+
// stays hermetic.
|
|
31
|
+
function buildInjectPayload(input) {
|
|
32
|
+
const confidence = envelope_1.RETRIEVAL_CONFIDENCES.includes(input.retrieval_confidence)
|
|
33
|
+
? input.retrieval_confidence
|
|
34
|
+
: "low";
|
|
35
|
+
const offered = input.offered_source_ids.filter((s) => typeof s === "string" && s.length > 0);
|
|
36
|
+
const offeredCount = Number.isFinite(input.evidence_offered)
|
|
37
|
+
? input.evidence_offered
|
|
38
|
+
: offered.length;
|
|
39
|
+
return {
|
|
40
|
+
inject_id: input.injectId ?? (0, event_id_1.mintEventId)(),
|
|
41
|
+
turn_index: input.turn_index,
|
|
42
|
+
evidence_offered: offeredCount,
|
|
43
|
+
offered_source_ids: offered,
|
|
44
|
+
evidence_tokens: Number.isFinite(input.evidence_tokens) ? input.evidence_tokens : 0,
|
|
45
|
+
retrieval_confidence: confidence,
|
|
46
|
+
retrieval_latency_ms: Number.isFinite(input.retrieval_latency_ms)
|
|
47
|
+
? input.retrieval_latency_ms
|
|
48
|
+
: 0,
|
|
49
|
+
zero_results: offeredCount === 0,
|
|
50
|
+
window_deadline: new Date(input.createdAtMs + exports.WINDOW_MS).toISOString(),
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
// deriveOutcome closes one inject's window if it is eligible, else returns null
|
|
54
|
+
// (the inject stays pending). Close precedence (§0, "whichever first"):
|
|
55
|
+
//
|
|
56
|
+
// turn_limit the full turn window has been observed (maxTurn >= turn+window).
|
|
57
|
+
// The agent had its whole opportunity; not-referenced => ignored.
|
|
58
|
+
// time_limit the 15-minute deadline passed before the turn window filled.
|
|
59
|
+
// The session went idle, so a not-referenced inject is unknown,
|
|
60
|
+
// not ignored: we did not observe the full opportunity. This is
|
|
61
|
+
// what makes Unknown Coverage a meaningful honesty term.
|
|
62
|
+
// still_open neither => null, stays pending.
|
|
63
|
+
//
|
|
64
|
+
// v1 used := referenced (§4.2): an inject that was pulled or cited is "used".
|
|
65
|
+
// The schema keeps referenced and used as separate fields so a later correlator
|
|
66
|
+
// can tighten "used" to material incorporation without a migration.
|
|
67
|
+
function deriveOutcome(inject, calls, citations, ctx) {
|
|
68
|
+
// No numeric turn means we cannot align the inject to pulls/citations; it can
|
|
69
|
+
// never be correlated, so leave it pending rather than guess an outcome.
|
|
70
|
+
if (inject.turn_index === null)
|
|
71
|
+
return null;
|
|
72
|
+
const window = ctx.window ?? exports.WINDOW_TURNS;
|
|
73
|
+
const maxTurn = ctx.maxTurnBySession.get(inject.session_id) ?? inject.turn_index;
|
|
74
|
+
const deadlineMs = Date.parse(inject.window_deadline);
|
|
75
|
+
let reason;
|
|
76
|
+
if (maxTurn >= inject.turn_index + window) {
|
|
77
|
+
reason = "turn_limit";
|
|
78
|
+
}
|
|
79
|
+
else if (Number.isFinite(deadlineMs) && ctx.nowMs >= deadlineMs) {
|
|
80
|
+
reason = "time_limit";
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
return null; // still open -> stays pending
|
|
84
|
+
}
|
|
85
|
+
// Reuse the ONE shared join (INV-ADOPTION-SOURCE-1): score this single inject
|
|
86
|
+
// turn against the window's pulls and citations.
|
|
87
|
+
const injectTurn = {
|
|
88
|
+
session_id: inject.session_id,
|
|
89
|
+
turn_index: inject.turn_index,
|
|
90
|
+
injected_source_ids: inject.offered_source_ids,
|
|
91
|
+
};
|
|
92
|
+
const [row] = (0, followthrough_1.computeFollowthrough)([injectTurn], calls, citations, window);
|
|
93
|
+
const pulled_within_window = row.a1a_pull;
|
|
94
|
+
const report_cited = row.a1b_push_reference;
|
|
95
|
+
const referenced = row.a1c_any;
|
|
96
|
+
// The offered ids that were referenced (pulled or cited), original form, deduped
|
|
97
|
+
// by the same normId rule the join uses.
|
|
98
|
+
const referencedByNorm = new Map();
|
|
99
|
+
for (const id of [...row.pulled_overlap, ...row.cited_overlap]) {
|
|
100
|
+
const n = (0, followthrough_1.normId)(id);
|
|
101
|
+
if (!referencedByNorm.has(n))
|
|
102
|
+
referencedByNorm.set(n, id);
|
|
103
|
+
}
|
|
104
|
+
const referenced_source_ids = Array.from(referencedByNorm.values());
|
|
105
|
+
let outcome;
|
|
106
|
+
if (referenced)
|
|
107
|
+
outcome = "used";
|
|
108
|
+
else if (reason === "turn_limit")
|
|
109
|
+
outcome = "ignored";
|
|
110
|
+
else
|
|
111
|
+
outcome = "unknown";
|
|
112
|
+
// offered_reference_rate: distinct offered ids referenced / distinct offered ids
|
|
113
|
+
// (the recall direction). null when nothing was offered.
|
|
114
|
+
const distinctOffered = new Set(inject.offered_source_ids.map(followthrough_1.normId));
|
|
115
|
+
const offered_reference_rate = distinctOffered.size
|
|
116
|
+
? referenced_source_ids.length / distinctOffered.size
|
|
117
|
+
: null;
|
|
118
|
+
// citation_precision (v1 hallucinated-id guard): of the distinct ids the report
|
|
119
|
+
// cited in this window, the fraction that resolve to one of THIS inject's
|
|
120
|
+
// offered ids. null when the report cited nothing in the window (undefined, not
|
|
121
|
+
// zero). v1 caveat: an id pointing to a real-but-not-offered doc counts against
|
|
122
|
+
// precision, so this is a conservative proxy, in step with the §4.2 v1 framing.
|
|
123
|
+
const citedInWindow = [];
|
|
124
|
+
for (const c of citations) {
|
|
125
|
+
if (c.session_id !== inject.session_id)
|
|
126
|
+
continue;
|
|
127
|
+
if (c.turn_index < inject.turn_index || c.turn_index > inject.turn_index + window)
|
|
128
|
+
continue;
|
|
129
|
+
citedInWindow.push(...c.source_ids);
|
|
130
|
+
}
|
|
131
|
+
const distinctCited = new Set(citedInWindow.map(followthrough_1.normId));
|
|
132
|
+
const validOffered = new Set(row.cited_overlap.map(followthrough_1.normId));
|
|
133
|
+
const citation_precision = distinctCited.size ? validOffered.size / distinctCited.size : null;
|
|
134
|
+
const payload = {
|
|
135
|
+
inject_id: inject.inject_id,
|
|
136
|
+
outcome_version: exports.OUTCOME_VERSION,
|
|
137
|
+
outcome,
|
|
138
|
+
pulled_within_window,
|
|
139
|
+
report_cited,
|
|
140
|
+
referenced,
|
|
141
|
+
referenced_source_ids,
|
|
142
|
+
citation_precision,
|
|
143
|
+
offered_reference_rate,
|
|
144
|
+
window_closed_reason: reason,
|
|
145
|
+
};
|
|
146
|
+
return {
|
|
147
|
+
event_id: (0, event_id_1.outcomeEventId)(inject.inject_id, exports.OUTCOME_VERSION),
|
|
148
|
+
payload,
|
|
149
|
+
};
|
|
150
|
+
}
|