@hiveai/core 0.10.1 → 0.10.3

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/dist/index.d.ts CHANGED
@@ -16,6 +16,56 @@ declare const AnchorSchema: z.ZodObject<{
16
16
  paths?: string[] | undefined;
17
17
  symbols?: string[] | undefined;
18
18
  }>;
19
+ /**
20
+ * An executable check derived from a memory — the "feedback computational" layer.
21
+ *
22
+ * A `gotcha`/`attempt` is normally feedforward (text the agent reads). A sensor turns
23
+ * that lesson into a deterministic check: when a touched file matches `pattern`, the
24
+ * memory's warning fires regardless of semantic ranking. This closes the harness loop —
25
+ * a documented mistake becomes a permanent guardrail.
26
+ *
27
+ * Phase 1 implements `kind: "regex"` only. `shell`/`test` are reserved for a later phase
28
+ * (they require I/O and must run from the CLI, not core).
29
+ */
30
+ declare const SensorSchema: z.ZodObject<{
31
+ kind: z.ZodDefault<z.ZodEnum<["regex", "shell", "test"]>>;
32
+ /** Regex source (for kind=regex), matched against added diff lines / file content. */
33
+ pattern: z.ZodOptional<z.ZodString>;
34
+ /** Regex flags (e.g. "i", "m"). Ignored for non-regex kinds. */
35
+ flags: z.ZodOptional<z.ZodString>;
36
+ /** Shell/test command to run (for kind=shell|test). Executed by the CLI, never by core. */
37
+ command: z.ZodOptional<z.ZodString>;
38
+ /** Glob-ish path prefixes the sensor applies to. Falls back to the memory's anchor paths when empty. */
39
+ paths: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
40
+ /** LLM-facing self-correction message: what was done wrong and what to do instead. */
41
+ message: z.ZodString;
42
+ /** `warn` surfaces in review; `block` can hard-block the commit (only when the gate opts in). */
43
+ severity: z.ZodDefault<z.ZodEnum<["warn", "block"]>>;
44
+ /** True when hAIve generated this sensor automatically (vs. hand-authored). */
45
+ autogen: z.ZodDefault<z.ZodBoolean>;
46
+ /** ISO timestamp of the last time this sensor matched a diff. */
47
+ last_fired: z.ZodDefault<z.ZodNullable<z.ZodString>>;
48
+ }, "strip", z.ZodTypeAny, {
49
+ message: string;
50
+ paths: string[];
51
+ kind: "regex" | "shell" | "test";
52
+ severity: "warn" | "block";
53
+ autogen: boolean;
54
+ last_fired: string | null;
55
+ pattern?: string | undefined;
56
+ flags?: string | undefined;
57
+ command?: string | undefined;
58
+ }, {
59
+ message: string;
60
+ paths?: string[] | undefined;
61
+ kind?: "regex" | "shell" | "test" | undefined;
62
+ pattern?: string | undefined;
63
+ flags?: string | undefined;
64
+ command?: string | undefined;
65
+ severity?: "warn" | "block" | undefined;
66
+ autogen?: boolean | undefined;
67
+ last_fired?: string | null | undefined;
68
+ }>;
19
69
  declare const MemoryFrontmatterSchema: z.ZodEffects<z.ZodObject<{
20
70
  id: z.ZodString;
21
71
  scope: z.ZodDefault<z.ZodEnum<["personal", "team", "module", "shared"]>>;
@@ -35,6 +85,46 @@ declare const MemoryFrontmatterSchema: z.ZodEffects<z.ZodObject<{
35
85
  paths?: string[] | undefined;
36
86
  symbols?: string[] | undefined;
37
87
  }>>;
88
+ /** Optional executable check derived from this memory (feedback computational layer). */
89
+ sensor: z.ZodOptional<z.ZodObject<{
90
+ kind: z.ZodDefault<z.ZodEnum<["regex", "shell", "test"]>>;
91
+ /** Regex source (for kind=regex), matched against added diff lines / file content. */
92
+ pattern: z.ZodOptional<z.ZodString>;
93
+ /** Regex flags (e.g. "i", "m"). Ignored for non-regex kinds. */
94
+ flags: z.ZodOptional<z.ZodString>;
95
+ /** Shell/test command to run (for kind=shell|test). Executed by the CLI, never by core. */
96
+ command: z.ZodOptional<z.ZodString>;
97
+ /** Glob-ish path prefixes the sensor applies to. Falls back to the memory's anchor paths when empty. */
98
+ paths: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
99
+ /** LLM-facing self-correction message: what was done wrong and what to do instead. */
100
+ message: z.ZodString;
101
+ /** `warn` surfaces in review; `block` can hard-block the commit (only when the gate opts in). */
102
+ severity: z.ZodDefault<z.ZodEnum<["warn", "block"]>>;
103
+ /** True when hAIve generated this sensor automatically (vs. hand-authored). */
104
+ autogen: z.ZodDefault<z.ZodBoolean>;
105
+ /** ISO timestamp of the last time this sensor matched a diff. */
106
+ last_fired: z.ZodDefault<z.ZodNullable<z.ZodString>>;
107
+ }, "strip", z.ZodTypeAny, {
108
+ message: string;
109
+ paths: string[];
110
+ kind: "regex" | "shell" | "test";
111
+ severity: "warn" | "block";
112
+ autogen: boolean;
113
+ last_fired: string | null;
114
+ pattern?: string | undefined;
115
+ flags?: string | undefined;
116
+ command?: string | undefined;
117
+ }, {
118
+ message: string;
119
+ paths?: string[] | undefined;
120
+ kind?: "regex" | "shell" | "test" | undefined;
121
+ pattern?: string | undefined;
122
+ flags?: string | undefined;
123
+ command?: string | undefined;
124
+ severity?: "warn" | "block" | undefined;
125
+ autogen?: boolean | undefined;
126
+ last_fired?: string | null | undefined;
127
+ }>>;
38
128
  tags: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
39
129
  domain: z.ZodOptional<z.ZodString>;
40
130
  author: z.ZodOptional<z.ZodString>;
@@ -73,6 +163,17 @@ declare const MemoryFrontmatterSchema: z.ZodEffects<z.ZodObject<{
73
163
  revision_count: number;
74
164
  requires_human_approval: boolean;
75
165
  module?: string | undefined;
166
+ sensor?: {
167
+ message: string;
168
+ paths: string[];
169
+ kind: "regex" | "shell" | "test";
170
+ severity: "warn" | "block";
171
+ autogen: boolean;
172
+ last_fired: string | null;
173
+ pattern?: string | undefined;
174
+ flags?: string | undefined;
175
+ command?: string | undefined;
176
+ } | undefined;
76
177
  domain?: string | undefined;
77
178
  author?: string | undefined;
78
179
  topic?: string | undefined;
@@ -88,6 +189,17 @@ declare const MemoryFrontmatterSchema: z.ZodEffects<z.ZodObject<{
88
189
  paths?: string[] | undefined;
89
190
  symbols?: string[] | undefined;
90
191
  } | undefined;
192
+ sensor?: {
193
+ message: string;
194
+ paths?: string[] | undefined;
195
+ kind?: "regex" | "shell" | "test" | undefined;
196
+ pattern?: string | undefined;
197
+ flags?: string | undefined;
198
+ command?: string | undefined;
199
+ severity?: "warn" | "block" | undefined;
200
+ autogen?: boolean | undefined;
201
+ last_fired?: string | null | undefined;
202
+ } | undefined;
91
203
  tags?: string[] | undefined;
92
204
  domain?: string | undefined;
93
205
  author?: string | undefined;
@@ -119,6 +231,17 @@ declare const MemoryFrontmatterSchema: z.ZodEffects<z.ZodObject<{
119
231
  revision_count: number;
120
232
  requires_human_approval: boolean;
121
233
  module?: string | undefined;
234
+ sensor?: {
235
+ message: string;
236
+ paths: string[];
237
+ kind: "regex" | "shell" | "test";
238
+ severity: "warn" | "block";
239
+ autogen: boolean;
240
+ last_fired: string | null;
241
+ pattern?: string | undefined;
242
+ flags?: string | undefined;
243
+ command?: string | undefined;
244
+ } | undefined;
122
245
  domain?: string | undefined;
123
246
  author?: string | undefined;
124
247
  topic?: string | undefined;
@@ -134,6 +257,17 @@ declare const MemoryFrontmatterSchema: z.ZodEffects<z.ZodObject<{
134
257
  paths?: string[] | undefined;
135
258
  symbols?: string[] | undefined;
136
259
  } | undefined;
260
+ sensor?: {
261
+ message: string;
262
+ paths?: string[] | undefined;
263
+ kind?: "regex" | "shell" | "test" | undefined;
264
+ pattern?: string | undefined;
265
+ flags?: string | undefined;
266
+ command?: string | undefined;
267
+ severity?: "warn" | "block" | undefined;
268
+ autogen?: boolean | undefined;
269
+ last_fired?: string | null | undefined;
270
+ } | undefined;
137
271
  tags?: string[] | undefined;
138
272
  domain?: string | undefined;
139
273
  author?: string | undefined;
@@ -167,6 +301,7 @@ type MemoryScope = z.infer<typeof MemoryScopeSchema>;
167
301
  type MemoryStatus = z.infer<typeof MemoryStatusSchema>;
168
302
  type MemoryType = z.infer<typeof MemoryTypeSchema>;
169
303
  type Anchor = z.infer<typeof AnchorSchema>;
304
+ type Sensor = z.infer<typeof SensorSchema>;
170
305
  type MemoryFrontmatter = z.infer<typeof MemoryFrontmatterSchema>;
171
306
  interface Memory {
172
307
  frontmatter: MemoryFrontmatter;
@@ -939,4 +1074,67 @@ interface RetirementSignal {
939
1074
  declare function retirementSignal(fm: MemoryFrontmatter, body?: string, now?: Date): RetirementSignal;
940
1075
  declare function isRetiredMemory(fm: MemoryFrontmatter, body?: string, now?: Date): boolean;
941
1076
 
942
- export { AUTOPILOT_DEFAULTS, type Anchor, AnchorSchema, type AntiPatternGate, type AutoPromoteRule, BRIEFING_MARKER_TTL_MS, BRIEFING_PRESET_DEFAULTS, type BreakingChange, type BriefingBudgetNumbers, type BriefingBudgetPreset, type BriefingMarker, type BudgetPart, type BudgetSlice, type BuildCodeMapOptions, CHARS_PER_TOKEN, CODE_MAP_FILE, CONFIG_FILE, type CodeExport, type CodeExportKind, type CodeFileEntry, type CodeMap, type CodeMapQueryOptions, type CollectTimelineOpts, type ConfidenceLevel, type ConfidenceThresholds, type ConflictCandidatePair, type ConflictCandidatesOpts, type ContractDiffResult, type ContractFile, type ContractSnapshot, CrossRepoProvenanceSchema, type CrossRepoReport, type CrossRepoSource, DECAY_DAYS, DEFAULT_AUTO_PROMOTE_RULE, DEFAULT_CONFIDENCE_THRESHOLDS, DEFAULT_CONFIG, type DepChange, type DepTrackResult, type DependencySnapshot, GUESSABLE_THRESHOLD, HAIVE_DIR, type HaiveConfig, type HaivePaths, type LexicalRankResult, type LoadedMemory, MEMORIES_DIR, type Memory, type MemoryFrontmatter, MemoryFrontmatterSchema, type MemoryScope, MemoryScopeSchema, type MemoryStatus, MemoryStatusSchema, type MemoryType, MemoryTypeSchema, type MemoryUsage, PROJECT_CONTEXT_FILE, RUNTIME_JOURNAL_FILENAME, type ResolveProjectInfo, type RetirementSignal, type RuntimeJournalEntry, SESSION_RECAP_TTL_MS, STACK_PACK_TAG, type TimelineEntry, type TopicStatusPair, type TruncateOptions, type TruncateResult, USAGE_FILE, USAGE_LOG_DIR, USAGE_LOG_FILE, type UsageAggregate, type UsageEvent, type UsageIndex, type VerifyOptions, type VerifyResult, aggregateUsage, allocateBudget, antiPatternGateParams, appendRuntimeJournalEntry, appendUsageEvent, briefingMarkerPath, briefingMarkersDir, buildCodeMap, buildFrontmatter, bumpRead, codeMapPath, collectTimelineEntries, configPath, contractLockPath, deriveConfidence, diffContract, emptyUsage, emptyUsageIndex, enforcementDir, estimateTokens, extractActionsBriefBody, extractSnippet, findLexicalConflictPairs, findProjectRoot, findTopicStatusConflictPairs, firstMemoryOneLine, getUsage, globToRegExp, hasRecentBriefingMarker, inferModulesFromPaths, isAutoPromoteEligible, isDecaying, isFreshIsoDate, isGlobPath, isLikelyGuessable, isRetiredMemory, isStackPackSeed, listMarkdownFilesRecursive, literalMatchesAllTokens, literalMatchesAnyToken, loadCodeMap, loadConfig, loadConfigSync, loadMemoriesFromDir, loadMemory, loadUsageIndex, memoryFilePath, memoryMatchesAnchorPaths, newMemoryId, normalizeSessionId, parseMemory, parseSince, pathsOverlap, pickSnippetNeedle, pullCrossRepoSources, queryCodeMap, rankMemoriesLexical, readRecentBriefingMarker, readRuntimeJournalTail, readUsageEvents, recordRejection, relPathFrom, resolveBriefingBudget, resolveHaivePaths, resolveManifestFiles, resolveProjectInfo, retirementSignal, runtimeJournalPath, saveCodeMap, saveConfig, saveUsageIndex, serializeMemory, snapshotContract, specificityScore, stripPrivate, suggestTopicKey, tokenizeQuery, trackDependencies, trackReads, truncateToTokens, usageLogPath, usageLogSize, usagePath, verifyAnchor, watchContracts, writeBriefingMarker };
1077
+ /**
1078
+ * Sensors — the feedback *computational* layer of the harness.
1079
+ *
1080
+ * A memory's `sensor` turns a documented lesson (gotcha/attempt) into a deterministic
1081
+ * check. Unlike semantic anti-pattern matching (probabilistic, warmup-sensitive), a
1082
+ * regex sensor fires the same way every time, so a known mistake becomes a permanent
1083
+ * guardrail. Phase 1 supports `kind: "regex"` only — pure, no I/O. `shell`/`test`
1084
+ * sensors are recognized but not executed here (they must run from the CLI).
1085
+ */
1086
+ interface SensorHit {
1087
+ /** The memory id whose sensor matched. */
1088
+ memory_id: string;
1089
+ /** The sensor that matched. */
1090
+ sensor: Sensor;
1091
+ /** Project-relative file the match was found in (when known). */
1092
+ file?: string;
1093
+ /** The matched line (trimmed, capped) — useful for review output. */
1094
+ matched_line?: string;
1095
+ /** LLM-facing self-correction message carried from the sensor. */
1096
+ message: string;
1097
+ severity: Sensor["severity"];
1098
+ }
1099
+ /** A unit of code to scan: a file path plus the text to match against. */
1100
+ interface SensorTarget {
1101
+ /** Project-relative path (used for path scoping and reporting). */
1102
+ path: string;
1103
+ /**
1104
+ * Text to scan. For a diff, pass only the added lines (callers should pre-filter)
1105
+ * so a sensor fires on "you introduced the bad pattern", not "you touched a file
1106
+ * that merely mentions it".
1107
+ */
1108
+ content: string;
1109
+ }
1110
+ /**
1111
+ * Does this sensor apply to `path`? A sensor with no explicit `paths` (and whose
1112
+ * memory has no anchor paths) applies everywhere. Otherwise it applies when the path
1113
+ * starts with, or contains, any configured prefix.
1114
+ */
1115
+ declare function sensorAppliesToPath(sensor: Sensor, anchorPaths: string[], path: string): boolean;
1116
+ /**
1117
+ * Compile a regex sensor. Returns null when the sensor is not a runnable regex
1118
+ * (wrong kind, missing/invalid pattern) so callers can skip it safely.
1119
+ */
1120
+ declare function compileRegexSensor(sensor: Sensor): RegExp | null;
1121
+ /**
1122
+ * Run a single regex sensor over one target. Returns the first matching line as a hit,
1123
+ * or null. Deterministic and side-effect-free.
1124
+ */
1125
+ declare function runRegexSensor(memoryId: string, sensor: Sensor, target: SensorTarget): SensorHit | null;
1126
+ /**
1127
+ * Run every memory's regex sensor against every applicable target.
1128
+ *
1129
+ * Memories without a sensor, or with a non-regex sensor, are skipped (non-regex kinds
1130
+ * are the CLI's responsibility). At most one hit per (memory, file) pair is returned.
1131
+ */
1132
+ declare function runSensors(memories: Memory[], targets: SensorTarget[]): SensorHit[];
1133
+ /**
1134
+ * Extract the added lines from a unified diff (lines starting with a single `+`,
1135
+ * excluding the `+++` file header). Mirrors the diff-handling already used by the
1136
+ * anti-pattern tokenizer so sensors fire on introductions, not mere mentions.
1137
+ */
1138
+ declare function addedLinesFromDiff(diff: string): string;
1139
+
1140
+ export { AUTOPILOT_DEFAULTS, type Anchor, AnchorSchema, type AntiPatternGate, type AutoPromoteRule, BRIEFING_MARKER_TTL_MS, BRIEFING_PRESET_DEFAULTS, type BreakingChange, type BriefingBudgetNumbers, type BriefingBudgetPreset, type BriefingMarker, type BudgetPart, type BudgetSlice, type BuildCodeMapOptions, CHARS_PER_TOKEN, CODE_MAP_FILE, CONFIG_FILE, type CodeExport, type CodeExportKind, type CodeFileEntry, type CodeMap, type CodeMapQueryOptions, type CollectTimelineOpts, type ConfidenceLevel, type ConfidenceThresholds, type ConflictCandidatePair, type ConflictCandidatesOpts, type ContractDiffResult, type ContractFile, type ContractSnapshot, CrossRepoProvenanceSchema, type CrossRepoReport, type CrossRepoSource, DECAY_DAYS, DEFAULT_AUTO_PROMOTE_RULE, DEFAULT_CONFIDENCE_THRESHOLDS, DEFAULT_CONFIG, type DepChange, type DepTrackResult, type DependencySnapshot, GUESSABLE_THRESHOLD, HAIVE_DIR, type HaiveConfig, type HaivePaths, type LexicalRankResult, type LoadedMemory, MEMORIES_DIR, type Memory, type MemoryFrontmatter, MemoryFrontmatterSchema, type MemoryScope, MemoryScopeSchema, type MemoryStatus, MemoryStatusSchema, type MemoryType, MemoryTypeSchema, type MemoryUsage, PROJECT_CONTEXT_FILE, RUNTIME_JOURNAL_FILENAME, type ResolveProjectInfo, type RetirementSignal, type RuntimeJournalEntry, SESSION_RECAP_TTL_MS, STACK_PACK_TAG, type Sensor, type SensorHit, SensorSchema, type SensorTarget, type TimelineEntry, type TopicStatusPair, type TruncateOptions, type TruncateResult, USAGE_FILE, USAGE_LOG_DIR, USAGE_LOG_FILE, type UsageAggregate, type UsageEvent, type UsageIndex, type VerifyOptions, type VerifyResult, addedLinesFromDiff, aggregateUsage, allocateBudget, antiPatternGateParams, appendRuntimeJournalEntry, appendUsageEvent, briefingMarkerPath, briefingMarkersDir, buildCodeMap, buildFrontmatter, bumpRead, codeMapPath, collectTimelineEntries, compileRegexSensor, configPath, contractLockPath, deriveConfidence, diffContract, emptyUsage, emptyUsageIndex, enforcementDir, estimateTokens, extractActionsBriefBody, extractSnippet, findLexicalConflictPairs, findProjectRoot, findTopicStatusConflictPairs, firstMemoryOneLine, getUsage, globToRegExp, hasRecentBriefingMarker, inferModulesFromPaths, isAutoPromoteEligible, isDecaying, isFreshIsoDate, isGlobPath, isLikelyGuessable, isRetiredMemory, isStackPackSeed, listMarkdownFilesRecursive, literalMatchesAllTokens, literalMatchesAnyToken, loadCodeMap, loadConfig, loadConfigSync, loadMemoriesFromDir, loadMemory, loadUsageIndex, memoryFilePath, memoryMatchesAnchorPaths, newMemoryId, normalizeSessionId, parseMemory, parseSince, pathsOverlap, pickSnippetNeedle, pullCrossRepoSources, queryCodeMap, rankMemoriesLexical, readRecentBriefingMarker, readRuntimeJournalTail, readUsageEvents, recordRejection, relPathFrom, resolveBriefingBudget, resolveHaivePaths, resolveManifestFiles, resolveProjectInfo, retirementSignal, runRegexSensor, runSensors, runtimeJournalPath, saveCodeMap, saveConfig, saveUsageIndex, sensorAppliesToPath, serializeMemory, snapshotContract, specificityScore, stripPrivate, suggestTopicKey, tokenizeQuery, trackDependencies, trackReads, truncateToTokens, usageLogPath, usageLogSize, usagePath, verifyAnchor, watchContracts, writeBriefingMarker };
package/dist/index.js CHANGED
@@ -27,6 +27,25 @@ var AnchorSchema = z.object({
27
27
  paths: z.array(z.string()).default([]),
28
28
  symbols: z.array(z.string()).default([])
29
29
  });
30
+ var SensorSchema = z.object({
31
+ kind: z.enum(["regex", "shell", "test"]).default("regex"),
32
+ /** Regex source (for kind=regex), matched against added diff lines / file content. */
33
+ pattern: z.string().optional(),
34
+ /** Regex flags (e.g. "i", "m"). Ignored for non-regex kinds. */
35
+ flags: z.string().optional(),
36
+ /** Shell/test command to run (for kind=shell|test). Executed by the CLI, never by core. */
37
+ command: z.string().optional(),
38
+ /** Glob-ish path prefixes the sensor applies to. Falls back to the memory's anchor paths when empty. */
39
+ paths: z.array(z.string()).default([]),
40
+ /** LLM-facing self-correction message: what was done wrong and what to do instead. */
41
+ message: z.string().min(1),
42
+ /** `warn` surfaces in review; `block` can hard-block the commit (only when the gate opts in). */
43
+ severity: z.enum(["warn", "block"]).default("warn"),
44
+ /** True when hAIve generated this sensor automatically (vs. hand-authored). */
45
+ autogen: z.boolean().default(false),
46
+ /** ISO timestamp of the last time this sensor matched a diff. */
47
+ last_fired: z.string().nullable().default(null)
48
+ });
30
49
  var IsoDateString = z.union([z.string(), z.date()]).transform((v) => v instanceof Date ? v.toISOString() : v).pipe(z.string().datetime());
31
50
  var MemoryFrontmatterSchema = z.object({
32
51
  id: z.string().min(1),
@@ -35,6 +54,8 @@ var MemoryFrontmatterSchema = z.object({
35
54
  type: MemoryTypeSchema,
36
55
  status: MemoryStatusSchema.default("draft"),
37
56
  anchor: AnchorSchema.default({ paths: [], symbols: [] }),
57
+ /** Optional executable check derived from this memory (feedback computational layer). */
58
+ sensor: SensorSchema.optional(),
38
59
  tags: z.array(z.string()).default([]),
39
60
  domain: z.string().optional(),
40
61
  author: z.string().optional(),
@@ -2442,6 +2463,57 @@ function retirementSignal(fm, body = "", now = /* @__PURE__ */ new Date()) {
2442
2463
  function isRetiredMemory(fm, body = "", now = /* @__PURE__ */ new Date()) {
2443
2464
  return retirementSignal(fm, body, now).retired;
2444
2465
  }
2466
+
2467
+ // src/sensors.ts
2468
+ function sensorAppliesToPath(sensor, anchorPaths, path15) {
2469
+ const scopes = sensor.paths.length > 0 ? sensor.paths : anchorPaths;
2470
+ if (scopes.length === 0) return true;
2471
+ return scopes.some((p) => path15 === p || path15.startsWith(p) || path15.includes(p));
2472
+ }
2473
+ function compileRegexSensor(sensor) {
2474
+ if (sensor.kind !== "regex" || !sensor.pattern) return null;
2475
+ try {
2476
+ const flags = new Set(["m", ...(sensor.flags ?? "").split("")].filter(Boolean));
2477
+ return new RegExp(sensor.pattern, [...flags].join(""));
2478
+ } catch {
2479
+ return null;
2480
+ }
2481
+ }
2482
+ function runRegexSensor(memoryId, sensor, target) {
2483
+ const re = compileRegexSensor(sensor);
2484
+ if (!re) return null;
2485
+ for (const rawLine of target.content.split("\n")) {
2486
+ re.lastIndex = 0;
2487
+ if (re.test(rawLine)) {
2488
+ return {
2489
+ memory_id: memoryId,
2490
+ sensor,
2491
+ file: target.path,
2492
+ matched_line: rawLine.trim().slice(0, 200),
2493
+ message: sensor.message,
2494
+ severity: sensor.severity
2495
+ };
2496
+ }
2497
+ }
2498
+ return null;
2499
+ }
2500
+ function runSensors(memories, targets) {
2501
+ const hits = [];
2502
+ for (const memory of memories) {
2503
+ const sensor = memory.frontmatter.sensor;
2504
+ if (!sensor || sensor.kind !== "regex") continue;
2505
+ const anchorPaths = memory.frontmatter.anchor.paths;
2506
+ for (const target of targets) {
2507
+ if (!sensorAppliesToPath(sensor, anchorPaths, target.path)) continue;
2508
+ const hit = runRegexSensor(memory.frontmatter.id, sensor, target);
2509
+ if (hit) hits.push(hit);
2510
+ }
2511
+ }
2512
+ return hits;
2513
+ }
2514
+ function addedLinesFromDiff(diff) {
2515
+ return diff.split("\n").filter((l) => l.startsWith("+") && !l.startsWith("+++")).map((l) => l.slice(1)).join("\n");
2516
+ }
2445
2517
  export {
2446
2518
  AUTOPILOT_DEFAULTS,
2447
2519
  AnchorSchema,
@@ -2466,9 +2538,11 @@ export {
2466
2538
  RUNTIME_JOURNAL_FILENAME,
2467
2539
  SESSION_RECAP_TTL_MS,
2468
2540
  STACK_PACK_TAG,
2541
+ SensorSchema,
2469
2542
  USAGE_FILE,
2470
2543
  USAGE_LOG_DIR,
2471
2544
  USAGE_LOG_FILE,
2545
+ addedLinesFromDiff,
2472
2546
  aggregateUsage,
2473
2547
  allocateBudget,
2474
2548
  antiPatternGateParams,
@@ -2481,6 +2555,7 @@ export {
2481
2555
  bumpRead,
2482
2556
  codeMapPath,
2483
2557
  collectTimelineEntries,
2558
+ compileRegexSensor,
2484
2559
  configPath,
2485
2560
  contractLockPath,
2486
2561
  deriveConfidence,
@@ -2536,10 +2611,13 @@ export {
2536
2611
  resolveManifestFiles,
2537
2612
  resolveProjectInfo,
2538
2613
  retirementSignal,
2614
+ runRegexSensor,
2615
+ runSensors,
2539
2616
  runtimeJournalPath,
2540
2617
  saveCodeMap,
2541
2618
  saveConfig,
2542
2619
  saveUsageIndex,
2620
+ sensorAppliesToPath,
2543
2621
  serializeMemory,
2544
2622
  snapshotContract,
2545
2623
  specificityScore,