@hivelore/core 0.38.0 → 0.39.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.
package/dist/index.d.ts CHANGED
@@ -2006,6 +2006,26 @@ declare function isSensorScannablePath(p: string): boolean;
2006
2006
  * with bare content) — never when every header was a Hivelore-owned path, so `.ai/`-only diffs scan nothing.
2007
2007
  */
2008
2008
  declare function scannableSensorTargets(diff: string): SensorTarget[];
2009
+ interface SensorWeakening {
2010
+ /** The `.ai/memories/**` file whose sensor the diff weakens. */
2011
+ file: string;
2012
+ /** Memory id derived from the filename (best-effort). */
2013
+ memory_id: string;
2014
+ change: "severity-demoted" | "oracle-changed" | "oracle-removed" | "sensor-removed" | "memory-deleted" | "suppression-broadened";
2015
+ detail: string;
2016
+ }
2017
+ /**
2018
+ * Detect diff hunks that WEAKEN the enforcement surface: demoting a block sensor to warn, changing
2019
+ * or removing its oracle (`pattern`/`command`), broadening its `absent` suppression, deleting the
2020
+ * whole sensor block, or deleting a memory file that carried a block sensor.
2021
+ *
2022
+ * Rationale: the gate is written in `.ai/` — the same tree the agent it constrains can edit. A
2023
+ * legitimate demotion exists (that's why this yields REVIEW findings, never blocks), but a weakening
2024
+ * that sails through unmentioned is exactly how a documented lesson silently stops protecting.
2025
+ * Deterministic, pure, diff-text only. Additions (new sensors) never flag; removing `absent`
2026
+ * TIGHTENS a sensor and never flags.
2027
+ */
2028
+ declare function detectSensorWeakening(diff: string): SensorWeakening[];
2009
2029
  interface SensorSelfCheck {
2010
2030
  /** The sensor stays SILENT on the current, presumed-correct code — i.e. it won't false-positive. */
2011
2031
  silent_on_current: boolean;
@@ -2216,6 +2236,12 @@ interface ScaffoldOptions {
2216
2236
  * test path and run command are placed inside it. Empty/omitted → repo root.
2217
2237
  */
2218
2238
  baseDir?: string;
2239
+ /**
2240
+ * Override the propose command embedded in the header and returned. Used by multi-package
2241
+ * scaffolds: a memory carries ONE sensor, so several generated tests share a single proposal
2242
+ * whose command chains every run command.
2243
+ */
2244
+ proposeCommandOverride?: string;
2219
2245
  }
2220
2246
  /** Map a user-supplied framework string (with common aliases) to a TestFramework, or null. */
2221
2247
  declare function normalizeFramework(input: string): TestFramework | null;
@@ -2242,8 +2268,49 @@ declare function parseLessonFields(body: string): {
2242
2268
  whyFailed?: string;
2243
2269
  instead?: string;
2244
2270
  };
2271
+ /**
2272
+ * Build the `sensors propose --kind test` line that arms a written post-incident test as the
2273
+ * lesson's oracle. Exported so multi-package scaffolds can chain several run commands into ONE
2274
+ * proposal (a memory carries a single sensor).
2275
+ */
2276
+ declare function buildProposeCommand(lesson: PostIncidentLesson, runCommand: string): string;
2245
2277
  /** Build a scaffold for the given lesson + framework. Pure — the caller writes `content` to `relPath`. */
2246
2278
  declare function scaffoldPostIncidentTest(lesson: PostIncidentLesson, options: ScaffoldOptions): TestScaffold;
2279
+ /** First-line provenance marker every generated scaffold carries. */
2280
+ declare const SCAFFOLD_MARKER_RE: RegExp;
2281
+ /** Does this test file still carry a pending stub (todo/skip)? A pending test passes on ANYTHING. */
2282
+ declare function hasPendingTestMarker(content: string): boolean;
2283
+ /**
2284
+ * Pull the test-file paths out of an oracle command (`npx vitest run a.test.ts && pytest b.py`).
2285
+ * Pure and deliberately conservative: only tokens that LOOK like test files are returned — the
2286
+ * caller checks existence. Used to refuse arming a still-pending oracle as a block sensor.
2287
+ */
2288
+ declare function extractTestFilePathsFromCommand(command: string): string[];
2289
+ interface ScaffoldLoopGap {
2290
+ /** Memory id the scaffold was generated from (parsed from the provenance marker). */
2291
+ memory_id: string;
2292
+ /** Project-relative path of the scaffold file. */
2293
+ path: string;
2294
+ /** The stub is still pending (todo/skip) — the assertion was never written. */
2295
+ pending: boolean;
2296
+ /** The lesson carries a validated shell/test sensor — the oracle is routed to the gate. */
2297
+ armed: boolean;
2298
+ /** The referenced memory no longer exists (scaffold orphaned). */
2299
+ memory_missing: boolean;
2300
+ }
2301
+ /**
2302
+ * Cross-check written post-incident scaffolds against the corpus: a scaffold whose assertion is
2303
+ * still pending, or whose lesson has no armed command sensor, is an OPEN behaviour loop — the
2304
+ * incident is documented but nothing deterministic guards it yet. Pure: callers collect the files.
2305
+ * Returns only the gaps (closed loops are silent).
2306
+ */
2307
+ declare function assessScaffoldLoop(files: Array<{
2308
+ path: string;
2309
+ content: string;
2310
+ }>, memories: Array<{
2311
+ id: string;
2312
+ sensorKind?: "regex" | "shell" | "test" | null;
2313
+ }>): ScaffoldLoopGap[];
2247
2314
 
2248
2315
  /**
2249
2316
  * First-agent bootstrap state — is the repo's knowledge layer filled enough for later agents to rely on?
@@ -3093,4 +3160,4 @@ interface AgentContext {
3093
3160
  }
3094
3161
  declare function detectAgentContext(env?: Record<string, string | undefined>): AgentContext;
3095
3162
 
3096
- export { AUTOPILOT_DEFAULTS, type Activation, type ActivationContext, ActivationSchema, type AgentContext, type Anchor, AnchorSchema, type AntiPatternGate, type AppliedConflictResolution, type AstExport, type AutoPromoteRule, BRIDGE_MARKERS, BRIDGE_TARGETS, BRIDGE_TARGET_PATH, BRIEFING_MARKER_TTL_MS, BRIEFING_PRESET_DEFAULTS, type BootstrapAssessment, type BootstrapGap, type BootstrapGate, type BootstrapMetrics, type BootstrapState, type BootstrapStateInput, type BreakingChange, type BridgeFileOutput, type BridgeMemoryEntry, type BridgeSensor, type BridgeTarget, type BriefingBudgetNumbers, type BriefingBudgetPreset, type BriefingMarker, type BriefingProofLineOptions, type BudgetPart, type BudgetSlice, type BuildCodeMapOptions, CHARS_PER_TOKEN, CODE_MAP_DEFAULT_EXCLUDE, CODE_MAP_DEFAULT_INCLUDE, CODE_MAP_FILE, CODE_STOPWORDS, CONFIG_FILE, type CaughtForYouOptions, type CaughtForYouRow, type CaughtForYouSummary, type CodeExport, type CodeExportKind, type CodeFileEntry, type CodeMap, type CodeMapQueryOptions, type CollectTimelineOpts, type CommandSensorSpec, type ConfidenceLevel, type ConfidenceThresholds, type ConflictCandidatePair, type ConflictCandidatesOpts, type ConflictResolution, type ContractDiffResult, type ContractFile, type ContractSnapshot, type CoverageGap, type CoverageOptions, CrossRepoProvenanceSchema, type CrossRepoReport, type CrossRepoSource, DECAY_DAYS, DEFAULT_AUTO_PROMOTE_RULE, DEFAULT_BRIEFING_EXCLUDE_TAGS, DEFAULT_CONFIDENCE_THRESHOLDS, DEFAULT_CONFIG, DEFAULT_DORMANT_DAYS, DEFAULT_PRIORITY_SIGNALS, type DashboardOptions, type DashboardReport, type DepChange, type DepTrackResult, type DependencySnapshot, type DetectStacksInput, type DetectableStack, type DocFrequency, type DormantRow, type DraftOptions, type DraftsOptions, ENV_WORKAROUND_TAGS, type EvalDelta, type EvalHistoryEntry, type EvalReport, type EvalSpec, type EvalTrend, type FailureCoverageOptions, type FailureObservation, type FeedbackAdjustment, type FeedbackAdjustmentAction, type FeedbackAdjustmentOptions, type Finding, type FindingFormat, type FindingSeverity, GUESSABLE_THRESHOLD, type GateMissProposal, type GatePrecision, type GatePrecisionDelta, type GatePrecisionMetricDelta, type GateTuningSuggestion, type GenerateBridgesOptions, type GitCommit, type GitWatchPlan, type GitWatchState, HAIVE_DIR, HAIVE_OWNED_FILES, HANDOFF_FILENAME, HIVELORE_ATTRIBUTION, type HaiveConfig, type HaivePaths, type HotFile, type HotFileSource, type ImpactOptions, type ImpactRow, type ImpactScore, type ImpactSummary, type ImpactTier, type InvalidMemoryFile, type LexicalRankResult, type LoadedMemory, MEMORIES_DIR, MIN_WORD_LEN, type Memory, type MemoryDraft, type MemoryFrontmatter, MemoryFrontmatterSchema, type MemoryPriority, type MemoryScope, MemoryScopeSchema, type MemoryStatus, MemoryStatusSchema, type MemoryType, MemoryTypeSchema, type MemoryUsage, type MergeResult, type MetricDelta, PREVENTION_DEBOUNCE_MS, PROJECT_CONTEXT_FILE, PROJECT_CONTEXT_THROTTLE_MS, type PostIncidentLesson, type PreventionEvent, type PreventionEventDetail, type PreventionReceipt, type PreventionReceiptRow, type PreventionRow, type PreventionSource, type PreventionTrend, type PrioritySignals, type ProposedSensorVerdict, RUNTIME_JOURNAL_FILENAME, type RecurrenceReport, type RecurrenceRow, type ResolveProjectInfo, type RetirementSignal, type RetrievalAggregate, type RetrievalCase, type RetrievalCaseResult, type RuntimeJournalEntry, SEED_QUALITY_FLOOR, SENSOR_ABSENT_LOOKBACK, SENSOR_ABSENT_WINDOW, SESSION_RECAP_TTL_MS, STACK_PACK_TAG, type ScaffoldOptions, type SeedProposal, type SelfEvalOptions, type Sensor, type SensorAggregate, type SensorCase, type SensorCaseResult, type SensorEvaluation, type SensorEvaluationOutcome, type SensorEvaluationStage, type SensorFlap, type SensorHealth, type SensorHit, type SensorRow, SensorSchema, type SensorSeed, type SensorSelfCheck, type SensorSuggestionOptions, type SensorTarget, type SessionHandoffData, type SkillActivation, TEST_FRAMEWORKS, type TestFramework, type TestScaffold, type TimelineEntry, type TopicStatusPair, type TruncateOptions, type TruncateResult, USAGE_FILE, USAGE_LOG_DIR, USAGE_LOG_FILE, type UncapturedFailure, type UsageAggregate, type UsageEvent, type UsageIndex, type VerifyOptions, type VerifyResult, addedLinesFromDiff, aggregateRetrieval, aggregateSensors, aggregateUsage, allocateBudget, antiPatternGateParams, appendEvalHistory, appendPreventionEvent, appendRuntimeJournalEntry, appendSensorEvaluations, appendUsageEvent, applyConflictResolution, applyFeedbackAdjustment, assessBootstrapState, assessSensorHealth, bridgeMemorySummary, briefingMarkerPath, briefingMarkersDir, briefingProofLine, buildCodeMap, buildCoverageIndex, buildDashboard, buildDocFrequency, buildFrontmatter, buildHandoffMarkdown, buildPreventionReceipt, buildReport, bumpRead, classifyMemoryPriority, codeMapPath, collectTimelineEntries, compactAutoRecapBody, compareEvalReports, compareGatePrecision, compareImpact, compileRegexSensor, componentOf, computeEvalTrend, computeGatePrecision, computeImpact, computePreventionTrend, computeRecurrence, computeScopeHash, configPath, contractLockPath, countSourceFilesOnDisk, deriveConfidence, detectAgentContext, detectStacksFromManifests, diffContract, diffHasDistinctiveOverlap, distinctiveCap, draftsFromFindings, emptyUsage, emptyUsageIndex, enforcementDir, estimateTokens, evalHistoryPath, evaluateSkillActivation, existingGateMissShas, extractActionsBriefBody, extractReferencedPaths, extractSensorExamples, extractSnippet, filterNewDrafts, findCoverageGaps, findLexicalConflictPairs, findProjectRoot, findTopicStatusConflictPairs, findUncapturedFailures, findingBody, findingToDraft, firstMemoryOneLine, gatePassedShas, generateBridges, getUsage, globToRegExp, handoffAgeMs, handoffFilePath, hasRecentBriefingMarker, hashProjectContext, incidentSuffix, inferModulesFromPaths, isAutoPromoteEligible, isAutoRecap, isCovered, isDecaying, isDistinctiveToken, isEnvWorkaroundMemory, isFreshIsoDate, isGlobPath, isLikelyGuessable, isNoiseSubject, isRetiredMemory, isSensorScannablePath, isSkill, isSkillSuppressed, isStackPackSeed, isStylisticRule, isTemplateProjectContext, judgeProposedSensor, lessonShortName, listMarkdownFilesRecursive, literalMatchesAllTokens, literalMatchesAnyToken, loadCodeMap, loadConfig, loadConfigSync, loadEvalHistory, loadMemoriesFromDir, loadMemoriesFromDirDetailed, loadMemory, loadPreventionEvents, loadSensorLedger, loadUsageIndex, looksLikeGenericAdvice, meetsSeedQualityFloor, memoryFilePath, memoryHasExcludedTag, memoryMatchesAnchorPaths, mergeHotFiles, mergeMemoryVersions, moduleNameOf, newMemoryId, normalizeFindingSeverity, normalizeFramework, normalizeSessionId, overallScore, parseEslintJson, parseFileAst, parseFindings, parseLessonFields, parseMemory, parseNpmAudit, parseSarif, parseSince, parseSonar, pathsOverlap, pickSnippetNeedle, pickTestFramework, planConflictResolution, planGitWatch, prepareBridgeData, preventionLogPath, priorityRank, prioritySignals, projectContextRecentlyEmitted, proposeGateMissDrafts, proposeSeedsFromCommits, pullCrossRepoSources, quarantineNote, queryCodeMap, rankMemoriesLexical, readRecentBriefingMarker, readRuntimeJournalTail, readSessionHandoff, readUsageEvents, recommendFeedbackAdjustment, recordApplied, recordPrevention, recordPreventionHits, recordProjectContextEmission, recordRejection, relPathFrom, renderBootstrapChecklist, renderCaughtForYou, renderPreventionReceipt, renderPreventionReceiptShare, resolveBriefingBudget, resolveHaivePaths, resolveManifestFiles, resolveProjectInfo, retirementSignal, revertedShaFromCommit, runRegexSensor, runSensors, runtimeJournalPath, saveCodeMap, saveConfig, saveUsageIndex, scaffoldPostIncidentTest, scannableSensorTargets, scoreRetrievalCase, scoreSensorCase, selectCommandSensors, sensorAppliesToPath, sensorLedgerPath, sensorPatternBrittleness, sensorPromotedAtMap, sensorSelfCheck, sensorTargetsFromDiff, serializeMemory, snapshotContract, specificityScore, stripPrivate, suggestGate, suggestSensorFromMemory, suggestSensorSeed, suggestTopicKey, summarizeCaughtForYou, summarizeImpact, synthesizeSelfEvalCases, tallyHotFiles, titleFromBody, tokenizeQuery, tokenizeWords, trackDependencies, trackReads, truncateToTokens, usageLogPath, usageLogSize, usagePath, verifyAnchor, watchContracts, withQuarantineNote, withoutQuarantineNote, writeBriefingMarker, writeSessionHandoff };
3163
+ export { AUTOPILOT_DEFAULTS, type Activation, type ActivationContext, ActivationSchema, type AgentContext, type Anchor, AnchorSchema, type AntiPatternGate, type AppliedConflictResolution, type AstExport, type AutoPromoteRule, BRIDGE_MARKERS, BRIDGE_TARGETS, BRIDGE_TARGET_PATH, BRIEFING_MARKER_TTL_MS, BRIEFING_PRESET_DEFAULTS, type BootstrapAssessment, type BootstrapGap, type BootstrapGate, type BootstrapMetrics, type BootstrapState, type BootstrapStateInput, type BreakingChange, type BridgeFileOutput, type BridgeMemoryEntry, type BridgeSensor, type BridgeTarget, type BriefingBudgetNumbers, type BriefingBudgetPreset, type BriefingMarker, type BriefingProofLineOptions, type BudgetPart, type BudgetSlice, type BuildCodeMapOptions, CHARS_PER_TOKEN, CODE_MAP_DEFAULT_EXCLUDE, CODE_MAP_DEFAULT_INCLUDE, CODE_MAP_FILE, CODE_STOPWORDS, CONFIG_FILE, type CaughtForYouOptions, type CaughtForYouRow, type CaughtForYouSummary, type CodeExport, type CodeExportKind, type CodeFileEntry, type CodeMap, type CodeMapQueryOptions, type CollectTimelineOpts, type CommandSensorSpec, type ConfidenceLevel, type ConfidenceThresholds, type ConflictCandidatePair, type ConflictCandidatesOpts, type ConflictResolution, type ContractDiffResult, type ContractFile, type ContractSnapshot, type CoverageGap, type CoverageOptions, CrossRepoProvenanceSchema, type CrossRepoReport, type CrossRepoSource, DECAY_DAYS, DEFAULT_AUTO_PROMOTE_RULE, DEFAULT_BRIEFING_EXCLUDE_TAGS, DEFAULT_CONFIDENCE_THRESHOLDS, DEFAULT_CONFIG, DEFAULT_DORMANT_DAYS, DEFAULT_PRIORITY_SIGNALS, type DashboardOptions, type DashboardReport, type DepChange, type DepTrackResult, type DependencySnapshot, type DetectStacksInput, type DetectableStack, type DocFrequency, type DormantRow, type DraftOptions, type DraftsOptions, ENV_WORKAROUND_TAGS, type EvalDelta, type EvalHistoryEntry, type EvalReport, type EvalSpec, type EvalTrend, type FailureCoverageOptions, type FailureObservation, type FeedbackAdjustment, type FeedbackAdjustmentAction, type FeedbackAdjustmentOptions, type Finding, type FindingFormat, type FindingSeverity, GUESSABLE_THRESHOLD, type GateMissProposal, type GatePrecision, type GatePrecisionDelta, type GatePrecisionMetricDelta, type GateTuningSuggestion, type GenerateBridgesOptions, type GitCommit, type GitWatchPlan, type GitWatchState, HAIVE_DIR, HAIVE_OWNED_FILES, HANDOFF_FILENAME, HIVELORE_ATTRIBUTION, type HaiveConfig, type HaivePaths, type HotFile, type HotFileSource, type ImpactOptions, type ImpactRow, type ImpactScore, type ImpactSummary, type ImpactTier, type InvalidMemoryFile, type LexicalRankResult, type LoadedMemory, MEMORIES_DIR, MIN_WORD_LEN, type Memory, type MemoryDraft, type MemoryFrontmatter, MemoryFrontmatterSchema, type MemoryPriority, type MemoryScope, MemoryScopeSchema, type MemoryStatus, MemoryStatusSchema, type MemoryType, MemoryTypeSchema, type MemoryUsage, type MergeResult, type MetricDelta, PREVENTION_DEBOUNCE_MS, PROJECT_CONTEXT_FILE, PROJECT_CONTEXT_THROTTLE_MS, type PostIncidentLesson, type PreventionEvent, type PreventionEventDetail, type PreventionReceipt, type PreventionReceiptRow, type PreventionRow, type PreventionSource, type PreventionTrend, type PrioritySignals, type ProposedSensorVerdict, RUNTIME_JOURNAL_FILENAME, type RecurrenceReport, type RecurrenceRow, type ResolveProjectInfo, type RetirementSignal, type RetrievalAggregate, type RetrievalCase, type RetrievalCaseResult, type RuntimeJournalEntry, SCAFFOLD_MARKER_RE, SEED_QUALITY_FLOOR, SENSOR_ABSENT_LOOKBACK, SENSOR_ABSENT_WINDOW, SESSION_RECAP_TTL_MS, STACK_PACK_TAG, type ScaffoldLoopGap, type ScaffoldOptions, type SeedProposal, type SelfEvalOptions, type Sensor, type SensorAggregate, type SensorCase, type SensorCaseResult, type SensorEvaluation, type SensorEvaluationOutcome, type SensorEvaluationStage, type SensorFlap, type SensorHealth, type SensorHit, type SensorRow, SensorSchema, type SensorSeed, type SensorSelfCheck, type SensorSuggestionOptions, type SensorTarget, type SensorWeakening, type SessionHandoffData, type SkillActivation, TEST_FRAMEWORKS, type TestFramework, type TestScaffold, type TimelineEntry, type TopicStatusPair, type TruncateOptions, type TruncateResult, USAGE_FILE, USAGE_LOG_DIR, USAGE_LOG_FILE, type UncapturedFailure, type UsageAggregate, type UsageEvent, type UsageIndex, type VerifyOptions, type VerifyResult, addedLinesFromDiff, aggregateRetrieval, aggregateSensors, aggregateUsage, allocateBudget, antiPatternGateParams, appendEvalHistory, appendPreventionEvent, appendRuntimeJournalEntry, appendSensorEvaluations, appendUsageEvent, applyConflictResolution, applyFeedbackAdjustment, assessBootstrapState, assessScaffoldLoop, assessSensorHealth, bridgeMemorySummary, briefingMarkerPath, briefingMarkersDir, briefingProofLine, buildCodeMap, buildCoverageIndex, buildDashboard, buildDocFrequency, buildFrontmatter, buildHandoffMarkdown, buildPreventionReceipt, buildProposeCommand, buildReport, bumpRead, classifyMemoryPriority, codeMapPath, collectTimelineEntries, compactAutoRecapBody, compareEvalReports, compareGatePrecision, compareImpact, compileRegexSensor, componentOf, computeEvalTrend, computeGatePrecision, computeImpact, computePreventionTrend, computeRecurrence, computeScopeHash, configPath, contractLockPath, countSourceFilesOnDisk, deriveConfidence, detectAgentContext, detectSensorWeakening, detectStacksFromManifests, diffContract, diffHasDistinctiveOverlap, distinctiveCap, draftsFromFindings, emptyUsage, emptyUsageIndex, enforcementDir, estimateTokens, evalHistoryPath, evaluateSkillActivation, existingGateMissShas, extractActionsBriefBody, extractReferencedPaths, extractSensorExamples, extractSnippet, extractTestFilePathsFromCommand, filterNewDrafts, findCoverageGaps, findLexicalConflictPairs, findProjectRoot, findTopicStatusConflictPairs, findUncapturedFailures, findingBody, findingToDraft, firstMemoryOneLine, gatePassedShas, generateBridges, getUsage, globToRegExp, handoffAgeMs, handoffFilePath, hasPendingTestMarker, hasRecentBriefingMarker, hashProjectContext, incidentSuffix, inferModulesFromPaths, isAutoPromoteEligible, isAutoRecap, isCovered, isDecaying, isDistinctiveToken, isEnvWorkaroundMemory, isFreshIsoDate, isGlobPath, isLikelyGuessable, isNoiseSubject, isRetiredMemory, isSensorScannablePath, isSkill, isSkillSuppressed, isStackPackSeed, isStylisticRule, isTemplateProjectContext, judgeProposedSensor, lessonShortName, listMarkdownFilesRecursive, literalMatchesAllTokens, literalMatchesAnyToken, loadCodeMap, loadConfig, loadConfigSync, loadEvalHistory, loadMemoriesFromDir, loadMemoriesFromDirDetailed, loadMemory, loadPreventionEvents, loadSensorLedger, loadUsageIndex, looksLikeGenericAdvice, meetsSeedQualityFloor, memoryFilePath, memoryHasExcludedTag, memoryMatchesAnchorPaths, mergeHotFiles, mergeMemoryVersions, moduleNameOf, newMemoryId, normalizeFindingSeverity, normalizeFramework, normalizeSessionId, overallScore, parseEslintJson, parseFileAst, parseFindings, parseLessonFields, parseMemory, parseNpmAudit, parseSarif, parseSince, parseSonar, pathsOverlap, pickSnippetNeedle, pickTestFramework, planConflictResolution, planGitWatch, prepareBridgeData, preventionLogPath, priorityRank, prioritySignals, projectContextRecentlyEmitted, proposeGateMissDrafts, proposeSeedsFromCommits, pullCrossRepoSources, quarantineNote, queryCodeMap, rankMemoriesLexical, readRecentBriefingMarker, readRuntimeJournalTail, readSessionHandoff, readUsageEvents, recommendFeedbackAdjustment, recordApplied, recordPrevention, recordPreventionHits, recordProjectContextEmission, recordRejection, relPathFrom, renderBootstrapChecklist, renderCaughtForYou, renderPreventionReceipt, renderPreventionReceiptShare, resolveBriefingBudget, resolveHaivePaths, resolveManifestFiles, resolveProjectInfo, retirementSignal, revertedShaFromCommit, runRegexSensor, runSensors, runtimeJournalPath, saveCodeMap, saveConfig, saveUsageIndex, scaffoldPostIncidentTest, scannableSensorTargets, scoreRetrievalCase, scoreSensorCase, selectCommandSensors, sensorAppliesToPath, sensorLedgerPath, sensorPatternBrittleness, sensorPromotedAtMap, sensorSelfCheck, sensorTargetsFromDiff, serializeMemory, snapshotContract, specificityScore, stripPrivate, suggestGate, suggestSensorFromMemory, suggestSensorSeed, suggestTopicKey, summarizeCaughtForYou, summarizeImpact, synthesizeSelfEvalCases, tallyHotFiles, titleFromBody, tokenizeQuery, tokenizeWords, trackDependencies, trackReads, truncateToTokens, usageLogPath, usageLogSize, usagePath, verifyAnchor, watchContracts, withQuarantineNote, withoutQuarantineNote, writeBriefingMarker, writeSessionHandoff };
package/dist/index.js CHANGED
@@ -4035,6 +4035,79 @@ function scannableSensorTargets(diff) {
4035
4035
  if (all.length === 0) return [{ path: "", content: diff }];
4036
4036
  return all.filter((t) => isSensorScannablePath(t.path));
4037
4037
  }
4038
+ function diffFileChanges(diff) {
4039
+ const files = [];
4040
+ let current = null;
4041
+ let oldPath = null;
4042
+ for (const line of diff.split("\n")) {
4043
+ if (line.startsWith("--- ")) {
4044
+ const raw = line.slice(4).trim();
4045
+ oldPath = raw === "/dev/null" ? null : normalizeProjectPath(raw);
4046
+ continue;
4047
+ }
4048
+ if (line.startsWith("+++ ")) {
4049
+ const raw = line.slice(4).trim();
4050
+ const newPath = raw === "/dev/null" ? null : normalizeProjectPath(raw);
4051
+ current = {
4052
+ path: newPath ?? oldPath ?? "",
4053
+ deleted: newPath === null,
4054
+ removed: [],
4055
+ added: []
4056
+ };
4057
+ files.push(current);
4058
+ continue;
4059
+ }
4060
+ if (!current) continue;
4061
+ if (line.startsWith("-") && !line.startsWith("---")) current.removed.push(line.slice(1));
4062
+ else if (line.startsWith("+") && !line.startsWith("+++")) current.added.push(line.slice(1));
4063
+ }
4064
+ return files;
4065
+ }
4066
+ var SENSOR_ORACLE_KEY_RE = /^\s*(pattern|command):\s*(.*)$/;
4067
+ var SENSOR_ABSENT_KEY_RE = /^\s*absent:\s*(.*)$/;
4068
+ var SEVERITY_BLOCK_RE = /^\s*severity:\s*['"]?block['"]?\s*$/;
4069
+ var SEVERITY_WARN_RE = /^\s*severity:\s*['"]?warn['"]?\s*$/;
4070
+ var SENSOR_BLOCK_START_RE = /^\s*sensor:\s*$/;
4071
+ function detectSensorWeakening(diff) {
4072
+ const weakenings = [];
4073
+ for (const file of diffFileChanges(diff)) {
4074
+ if (!file.path.startsWith(".ai/memories/") || !file.path.endsWith(".md")) continue;
4075
+ const memoryId = file.path.replace(/^.*\//, "").replace(/\.md$/, "");
4076
+ const flag = (change, detail) => {
4077
+ weakenings.push({ file: file.path, memory_id: memoryId, change, detail });
4078
+ };
4079
+ const removedBlockSeverity = file.removed.some((l) => SEVERITY_BLOCK_RE.test(l));
4080
+ if (file.deleted) {
4081
+ if (file.removed.some((l) => SENSOR_BLOCK_START_RE.test(l)) && removedBlockSeverity) {
4082
+ flag("memory-deleted", "memory file with a block sensor deleted");
4083
+ }
4084
+ continue;
4085
+ }
4086
+ if (removedBlockSeverity && file.added.some((l) => SEVERITY_WARN_RE.test(l))) {
4087
+ flag("severity-demoted", "severity: block \u2192 warn");
4088
+ }
4089
+ for (const line of file.removed) {
4090
+ const m = line.match(SENSOR_ORACLE_KEY_RE);
4091
+ if (!m) continue;
4092
+ const key = m[1];
4093
+ const replacement = file.added.find((l) => l.match(SENSOR_ORACLE_KEY_RE)?.[1] === key);
4094
+ if (replacement === void 0) {
4095
+ flag("oracle-removed", `sensor ${key} removed`);
4096
+ } else if (replacement.trim() !== line.trim()) {
4097
+ flag("oracle-changed", `sensor ${key} changed`);
4098
+ }
4099
+ }
4100
+ const removedAbsent = file.removed.find((l) => SENSOR_ABSENT_KEY_RE.test(l));
4101
+ const addedAbsent = file.added.find((l) => SENSOR_ABSENT_KEY_RE.test(l));
4102
+ if (addedAbsent !== void 0 && addedAbsent.trim() !== removedAbsent?.trim()) {
4103
+ flag("suppression-broadened", removedAbsent === void 0 ? "absent marker added" : "absent marker changed");
4104
+ }
4105
+ if (file.removed.some((l) => SENSOR_BLOCK_START_RE.test(l)) && removedBlockSeverity && !file.added.some((l) => SENSOR_BLOCK_START_RE.test(l))) {
4106
+ flag("sensor-removed", "block sensor block deleted");
4107
+ }
4108
+ }
4109
+ return weakenings;
4110
+ }
4038
4111
  function sensorSelfCheck(sensor, input) {
4039
4112
  const firedOn = [];
4040
4113
  for (const target of input.currentTargets) {
@@ -4531,7 +4604,7 @@ function parseLessonFields(body) {
4531
4604
  const instead = body.match(/\*\*Instead,\s*use:\*\*\s*([^\n]+)/i)?.[1]?.trim();
4532
4605
  return { title, whyFailed, instead };
4533
4606
  }
4534
- function proposeCommand(lesson, runCommand) {
4607
+ function buildProposeCommand(lesson, runCommand) {
4535
4608
  const parts = [
4536
4609
  `hivelore sensors propose ${lesson.memoryId}`,
4537
4610
  "--kind test",
@@ -4559,6 +4632,7 @@ function scaffoldPostIncidentTest(lesson, options) {
4559
4632
  const framework = options.framework;
4560
4633
  const short = lessonShortName(lesson.memoryId);
4561
4634
  const desc = oneLine(lesson.title) || short;
4635
+ const propose = (run) => options.proposeCommandOverride ?? buildProposeCommand(lesson, run);
4562
4636
  let relPath;
4563
4637
  let runCommand;
4564
4638
  let content;
@@ -4570,7 +4644,7 @@ function scaffoldPostIncidentTest(lesson, options) {
4570
4644
 
4571
4645
  ` : "";
4572
4646
  content = `${header(lesson, hc)}
4573
- // ${proposeCommand(lesson, runCommand)}
4647
+ // ${propose(runCommand)}
4574
4648
 
4575
4649
  ` + importLine + `describe(${JSON.stringify(desc)}, () => {
4576
4650
  it.todo("reproduces ${lesson.memoryId} and stays fixed");
@@ -4587,7 +4661,7 @@ function scaffoldPostIncidentTest(lesson, options) {
4587
4661
  runCommand = `pytest ${relPath}`;
4588
4662
  const hc = (l) => l ? `# ${l}` : "#";
4589
4663
  content = `${header(lesson, hc)}
4590
- # ${proposeCommand(lesson, runCommand)}
4664
+ # ${propose(runCommand)}
4591
4665
 
4592
4666
  import pytest
4593
4667
 
@@ -4604,7 +4678,7 @@ def test_${fn}():
4604
4678
  runCommand = `go test ./${dir}/`;
4605
4679
  const hc = (l) => l ? `// ${l}` : "//";
4606
4680
  content = `${header(lesson, hc)}
4607
- // ${proposeCommand(lesson, runCommand)}
4681
+ // ${propose(runCommand)}
4608
4682
 
4609
4683
  package incidents
4610
4684
 
@@ -4616,7 +4690,36 @@ func Test${fn}(t *testing.T) {
4616
4690
  }
4617
4691
  `;
4618
4692
  }
4619
- return { framework, relPath, content, runCommand, proposeCommand: proposeCommand(lesson, runCommand) };
4693
+ return { framework, relPath, content, runCommand, proposeCommand: propose(runCommand) };
4694
+ }
4695
+ var SCAFFOLD_MARKER_RE = /Post-incident guard generated by Hivelore from (\S+?)\.?\s*$/m;
4696
+ var PENDING_MARKERS = [/\bit\.todo\(/, /\bpytest\.mark\.skip\b/, /\bt\.Skip\(/];
4697
+ function hasPendingTestMarker(content) {
4698
+ return PENDING_MARKERS.some((re) => re.test(content));
4699
+ }
4700
+ function extractTestFilePathsFromCommand(command) {
4701
+ const TEST_FILE_RE2 = /(\.(test|spec)\.[cm]?[jt]sx?|_test\.go|(^|\/)test_[\w.-]+\.py|\.(test|spec)\.py)$/;
4702
+ return command.split(/\s+/).map((t) => t.replace(/^["']+|["']+$/g, "")).filter((t) => t && !t.startsWith("-") && TEST_FILE_RE2.test(t));
4703
+ }
4704
+ function assessScaffoldLoop(files, memories) {
4705
+ const byId = new Map(memories.map((m) => [m.id, m]));
4706
+ const gaps = [];
4707
+ for (const file of files) {
4708
+ const memoryId = file.content.match(SCAFFOLD_MARKER_RE)?.[1];
4709
+ if (!memoryId) continue;
4710
+ const memory = byId.get(memoryId);
4711
+ const pending = PENDING_MARKERS.some((re) => re.test(file.content));
4712
+ const armed = memory?.sensorKind === "shell" || memory?.sensorKind === "test";
4713
+ if (!pending && armed) continue;
4714
+ gaps.push({
4715
+ memory_id: memoryId,
4716
+ path: file.path,
4717
+ pending,
4718
+ armed,
4719
+ memory_missing: memory === void 0
4720
+ });
4721
+ }
4722
+ return gaps;
4620
4723
  }
4621
4724
 
4622
4725
  // src/bootstrap-state.ts
@@ -4683,8 +4786,25 @@ function assessBootstrapState(input) {
4683
4786
  const missingModules = modulesRequired.filter(
4684
4787
  (c) => !input.existingModules.includes(moduleNameOf(c))
4685
4788
  );
4789
+ const blockSensorScopes = input.memories.filter(
4790
+ (m) => (m.memory.frontmatter.status === "validated" || m.memory.frontmatter.status === "proposed") && m.memory.frontmatter.sensor?.severity === "block"
4791
+ ).flatMap((m) => m.memory.frontmatter.sensor?.paths ?? []);
4792
+ const areaGuardedByScope = (component) => {
4793
+ const files = codeFiles.filter((f) => componentOf(f) === component);
4794
+ return blockSensorScopes.some((rawScope) => {
4795
+ const scope = rawScope.replace(/^\/+/, "").replace(/\/+$/, "");
4796
+ if (!scope) return false;
4797
+ if (isGlobPath(scope)) {
4798
+ const re = globToRegExp(scope);
4799
+ return files.some((f) => re.test(f));
4800
+ }
4801
+ return anchorMatchesComponent(scope, component);
4802
+ });
4803
+ };
4686
4804
  const memoryUncovered = components.filter((c) => !areaCovered(c, anchoredMemories));
4687
- const sensorUncovered = components.filter((c) => !areaCovered(c, sensorMemories));
4805
+ const sensorUncovered = components.filter(
4806
+ (c) => !areaCovered(c, sensorMemories) && !areaGuardedByScope(c)
4807
+ );
4688
4808
  const gaps = [];
4689
4809
  if (!projectContextFilled) {
4690
4810
  gaps.push({
@@ -5876,6 +5996,7 @@ export {
5876
5996
  PROJECT_CONTEXT_FILE,
5877
5997
  PROJECT_CONTEXT_THROTTLE_MS,
5878
5998
  RUNTIME_JOURNAL_FILENAME,
5999
+ SCAFFOLD_MARKER_RE,
5879
6000
  SEED_QUALITY_FLOOR,
5880
6001
  SENSOR_ABSENT_LOOKBACK,
5881
6002
  SENSOR_ABSENT_WINDOW,
@@ -5900,6 +6021,7 @@ export {
5900
6021
  applyConflictResolution,
5901
6022
  applyFeedbackAdjustment,
5902
6023
  assessBootstrapState,
6024
+ assessScaffoldLoop,
5903
6025
  assessSensorHealth,
5904
6026
  bridgeMemorySummary,
5905
6027
  briefingMarkerPath,
@@ -5912,6 +6034,7 @@ export {
5912
6034
  buildFrontmatter,
5913
6035
  buildHandoffMarkdown,
5914
6036
  buildPreventionReceipt,
6037
+ buildProposeCommand,
5915
6038
  buildReport,
5916
6039
  bumpRead,
5917
6040
  classifyMemoryPriority,
@@ -5934,6 +6057,7 @@ export {
5934
6057
  countSourceFilesOnDisk,
5935
6058
  deriveConfidence,
5936
6059
  detectAgentContext,
6060
+ detectSensorWeakening,
5937
6061
  detectStacksFromManifests,
5938
6062
  diffContract,
5939
6063
  diffHasDistinctiveOverlap,
@@ -5950,6 +6074,7 @@ export {
5950
6074
  extractReferencedPaths,
5951
6075
  extractSensorExamples,
5952
6076
  extractSnippet,
6077
+ extractTestFilePathsFromCommand,
5953
6078
  filterNewDrafts,
5954
6079
  findCoverageGaps,
5955
6080
  findLexicalConflictPairs,
@@ -5965,6 +6090,7 @@ export {
5965
6090
  globToRegExp,
5966
6091
  handoffAgeMs,
5967
6092
  handoffFilePath,
6093
+ hasPendingTestMarker,
5968
6094
  hasRecentBriefingMarker,
5969
6095
  hashProjectContext,
5970
6096
  incidentSuffix,