@hiveai/core 0.10.9 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +265 -1
- package/dist/index.js +286 -6
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -46,6 +46,14 @@ var SensorSchema = z.object({
|
|
|
46
46
|
/** ISO timestamp of the last time this sensor matched a diff. */
|
|
47
47
|
last_fired: z.string().nullable().default(null)
|
|
48
48
|
});
|
|
49
|
+
var ActivationSchema = z.object({
|
|
50
|
+
/** Case-insensitive substrings matched against the task text. */
|
|
51
|
+
keywords: z.array(z.string()).default([]),
|
|
52
|
+
/** Glob-ish path patterns matched against the files being edited. */
|
|
53
|
+
globs: z.array(z.string()).default([]),
|
|
54
|
+
/** Always activate (rare — for truly universal playbooks). */
|
|
55
|
+
always: z.boolean().default(false)
|
|
56
|
+
});
|
|
49
57
|
var IsoDateString = z.union([z.string(), z.date()]).transform((v) => v instanceof Date ? v.toISOString() : v).pipe(z.string().datetime());
|
|
50
58
|
var MemoryFrontmatterSchema = z.object({
|
|
51
59
|
id: z.string().min(1),
|
|
@@ -56,6 +64,8 @@ var MemoryFrontmatterSchema = z.object({
|
|
|
56
64
|
anchor: AnchorSchema.default({ paths: [], symbols: [] }),
|
|
57
65
|
/** Optional executable check derived from this memory (feedback computational layer). */
|
|
58
66
|
sensor: SensorSchema.optional(),
|
|
67
|
+
/** Optional progressive-disclosure triggers — only meaningful for `type: skill`. */
|
|
68
|
+
activation: ActivationSchema.optional(),
|
|
59
69
|
tags: z.array(z.string()).default([]),
|
|
60
70
|
domain: z.string().optional(),
|
|
61
71
|
author: z.string().optional(),
|
|
@@ -149,6 +159,7 @@ function buildFrontmatter(input) {
|
|
|
149
159
|
expires_when: null,
|
|
150
160
|
topic: input.topic,
|
|
151
161
|
sensor: input.sensor,
|
|
162
|
+
activation: input.activation,
|
|
152
163
|
revision_count: 0,
|
|
153
164
|
related_ids: input.relatedIds ?? []
|
|
154
165
|
});
|
|
@@ -583,9 +594,14 @@ function emptyUsage() {
|
|
|
583
594
|
last_read_at: null,
|
|
584
595
|
rejected_count: 0,
|
|
585
596
|
last_rejected_at: null,
|
|
586
|
-
rejection_reason: null
|
|
597
|
+
rejection_reason: null,
|
|
598
|
+
applied_count: 0,
|
|
599
|
+
last_applied_at: null
|
|
587
600
|
};
|
|
588
601
|
}
|
|
602
|
+
function normalizeUsage(stored) {
|
|
603
|
+
return { ...emptyUsage(), ...stored ?? {} };
|
|
604
|
+
}
|
|
589
605
|
function emptyUsageIndex() {
|
|
590
606
|
return {
|
|
591
607
|
version: 1,
|
|
@@ -615,13 +631,13 @@ async function saveUsageIndex(paths, index) {
|
|
|
615
631
|
await writeFile(file, JSON.stringify(index, null, 2), "utf8");
|
|
616
632
|
}
|
|
617
633
|
function getUsage(index, id) {
|
|
618
|
-
return index.by_id[id]
|
|
634
|
+
return normalizeUsage(index.by_id[id]);
|
|
619
635
|
}
|
|
620
636
|
function bumpRead(index, ids) {
|
|
621
637
|
if (ids.length === 0) return index;
|
|
622
638
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
623
639
|
for (const id of ids) {
|
|
624
|
-
const current = index.by_id[id]
|
|
640
|
+
const current = normalizeUsage(index.by_id[id]);
|
|
625
641
|
index.by_id[id] = {
|
|
626
642
|
...current,
|
|
627
643
|
read_count: current.read_count + 1,
|
|
@@ -631,7 +647,7 @@ function bumpRead(index, ids) {
|
|
|
631
647
|
return index;
|
|
632
648
|
}
|
|
633
649
|
function recordRejection(index, id, reason) {
|
|
634
|
-
const current = index.by_id[id]
|
|
650
|
+
const current = normalizeUsage(index.by_id[id]);
|
|
635
651
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
636
652
|
index.by_id[id] = {
|
|
637
653
|
...current,
|
|
@@ -641,6 +657,16 @@ function recordRejection(index, id, reason) {
|
|
|
641
657
|
};
|
|
642
658
|
return index;
|
|
643
659
|
}
|
|
660
|
+
function recordApplied(index, id) {
|
|
661
|
+
const current = normalizeUsage(index.by_id[id]);
|
|
662
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
663
|
+
index.by_id[id] = {
|
|
664
|
+
...current,
|
|
665
|
+
applied_count: current.applied_count + 1,
|
|
666
|
+
last_applied_at: now
|
|
667
|
+
};
|
|
668
|
+
return index;
|
|
669
|
+
}
|
|
644
670
|
var DECAY_DAYS = 90;
|
|
645
671
|
function isDecaying(usage, createdAt) {
|
|
646
672
|
const threshold = Date.now() - DECAY_DAYS * 24 * 60 * 60 * 1e3;
|
|
@@ -657,6 +683,206 @@ async function trackReads(paths, ids) {
|
|
|
657
683
|
return index;
|
|
658
684
|
}
|
|
659
685
|
|
|
686
|
+
// src/impact.ts
|
|
687
|
+
var MS_PER_DAY = 24 * 60 * 60 * 1e3;
|
|
688
|
+
var DEFAULT_DORMANT_DAYS = 120;
|
|
689
|
+
var READ_SATURATION = 32;
|
|
690
|
+
function clamp01(n) {
|
|
691
|
+
if (Number.isNaN(n)) return 0;
|
|
692
|
+
return Math.max(0, Math.min(1, n));
|
|
693
|
+
}
|
|
694
|
+
function hasSensorFired(fm) {
|
|
695
|
+
return Boolean(fm.sensor?.last_fired);
|
|
696
|
+
}
|
|
697
|
+
function isDeadStatus(fm) {
|
|
698
|
+
return fm.status === "stale" || fm.status === "deprecated" || fm.status === "rejected";
|
|
699
|
+
}
|
|
700
|
+
function computeImpact(fm, usage, options = {}) {
|
|
701
|
+
const now = options.now ?? /* @__PURE__ */ new Date();
|
|
702
|
+
const dormantDays = options.dormantDays ?? DEFAULT_DORMANT_DAYS;
|
|
703
|
+
const signals = [];
|
|
704
|
+
let raw = 0;
|
|
705
|
+
if (usage.read_count > 0) {
|
|
706
|
+
raw += Math.min(1, Math.log2(usage.read_count + 1) / Math.log2(READ_SATURATION + 1)) * 0.35;
|
|
707
|
+
signals.push(`read ${usage.read_count}\xD7`);
|
|
708
|
+
}
|
|
709
|
+
if (usage.applied_count > 0) {
|
|
710
|
+
raw += Math.min(1, usage.applied_count / 4) * 0.6;
|
|
711
|
+
signals.push(`applied ${usage.applied_count}\xD7`);
|
|
712
|
+
}
|
|
713
|
+
if (hasSensorFired(fm)) {
|
|
714
|
+
raw += 0.25;
|
|
715
|
+
signals.push("sensor fired");
|
|
716
|
+
}
|
|
717
|
+
if (usage.rejected_count > 0) {
|
|
718
|
+
raw -= Math.min(0.6, usage.rejected_count * 0.25);
|
|
719
|
+
signals.push(`rejected ${usage.rejected_count}\xD7`);
|
|
720
|
+
}
|
|
721
|
+
let score = clamp01(raw);
|
|
722
|
+
if (isDeadStatus(fm)) {
|
|
723
|
+
score *= 0.2;
|
|
724
|
+
signals.push(`status=${fm.status}`);
|
|
725
|
+
}
|
|
726
|
+
const anchor = usage.last_applied_at ?? usage.last_read_at ?? fm.created_at;
|
|
727
|
+
const ageDays = (now.getTime() - new Date(anchor).getTime()) / MS_PER_DAY;
|
|
728
|
+
const dormant = Number.isFinite(ageDays) && ageDays >= dormantDays && usage.applied_count === 0;
|
|
729
|
+
if (dormant) {
|
|
730
|
+
score *= 0.5;
|
|
731
|
+
signals.push(`dormant ${Math.floor(ageDays)}d`);
|
|
732
|
+
}
|
|
733
|
+
const tier = deriveTier(score, dormant, usage);
|
|
734
|
+
const pruneCandidate = isPruneCandidate(fm, usage, tier);
|
|
735
|
+
return { score: round3(score), tier, signals, pruneCandidate };
|
|
736
|
+
}
|
|
737
|
+
function deriveTier(score, dormant, usage) {
|
|
738
|
+
if (dormant && usage.read_count <= 1 && usage.applied_count === 0) return "dormant";
|
|
739
|
+
if (score >= 0.55) return "high";
|
|
740
|
+
if (score >= 0.2) return "medium";
|
|
741
|
+
return "low";
|
|
742
|
+
}
|
|
743
|
+
function isPruneCandidate(fm, usage, tier) {
|
|
744
|
+
if (fm.sensor || usage.applied_count > 0) return false;
|
|
745
|
+
if (isDeadStatus(fm)) return true;
|
|
746
|
+
if (usage.rejected_count > 0 && usage.rejected_count >= usage.read_count) return true;
|
|
747
|
+
if (tier === "dormant" && usage.read_count === 0) return true;
|
|
748
|
+
return false;
|
|
749
|
+
}
|
|
750
|
+
function round3(n) {
|
|
751
|
+
return Math.round(n * 1e3) / 1e3;
|
|
752
|
+
}
|
|
753
|
+
function compareImpact(a, b) {
|
|
754
|
+
if (b.score !== a.score) return b.score - a.score;
|
|
755
|
+
if (a.pruneCandidate !== b.pruneCandidate) return a.pruneCandidate ? 1 : -1;
|
|
756
|
+
return 0;
|
|
757
|
+
}
|
|
758
|
+
function summarizeImpact(scores) {
|
|
759
|
+
const summary = {
|
|
760
|
+
total: scores.length,
|
|
761
|
+
high: 0,
|
|
762
|
+
medium: 0,
|
|
763
|
+
low: 0,
|
|
764
|
+
dormant: 0,
|
|
765
|
+
prune_candidates: 0
|
|
766
|
+
};
|
|
767
|
+
for (const s of scores) {
|
|
768
|
+
summary[s.tier] += 1;
|
|
769
|
+
if (s.pruneCandidate) summary.prune_candidates += 1;
|
|
770
|
+
}
|
|
771
|
+
return summary;
|
|
772
|
+
}
|
|
773
|
+
|
|
774
|
+
// src/eval.ts
|
|
775
|
+
function round32(n) {
|
|
776
|
+
return Math.round(n * 1e3) / 1e3;
|
|
777
|
+
}
|
|
778
|
+
function uniq(ids) {
|
|
779
|
+
return [...new Set(ids)];
|
|
780
|
+
}
|
|
781
|
+
function scoreRetrievalCase(name, expectIds, surfacedRanked) {
|
|
782
|
+
const expect = uniq(expectIds);
|
|
783
|
+
const surfaced = uniq(surfacedRanked);
|
|
784
|
+
const surfacedSet = new Set(surfaced);
|
|
785
|
+
const hits = expect.filter((id) => surfacedSet.has(id));
|
|
786
|
+
const misses = expect.filter((id) => !surfacedSet.has(id));
|
|
787
|
+
let bestRank = null;
|
|
788
|
+
for (let i = 0; i < surfaced.length; i++) {
|
|
789
|
+
if (expect.includes(surfaced[i])) {
|
|
790
|
+
bestRank = i + 1;
|
|
791
|
+
break;
|
|
792
|
+
}
|
|
793
|
+
}
|
|
794
|
+
return {
|
|
795
|
+
name,
|
|
796
|
+
expect_ids: expect,
|
|
797
|
+
surfaced_ids: surfaced,
|
|
798
|
+
hits,
|
|
799
|
+
misses,
|
|
800
|
+
precision: surfaced.length === 0 ? 0 : round32(hits.length / surfaced.length),
|
|
801
|
+
recall: expect.length === 0 ? 1 : round32(hits.length / expect.length),
|
|
802
|
+
best_rank: bestRank
|
|
803
|
+
};
|
|
804
|
+
}
|
|
805
|
+
function aggregateRetrieval(cases) {
|
|
806
|
+
const n = cases.length;
|
|
807
|
+
const mean = (sel) => n === 0 ? 0 : round32(cases.reduce((s, c) => s + sel(c), 0) / n);
|
|
808
|
+
return {
|
|
809
|
+
cases,
|
|
810
|
+
mean_precision: mean((c) => c.precision),
|
|
811
|
+
mean_recall: mean((c) => c.recall),
|
|
812
|
+
mrr: mean((c) => c.best_rank ? 1 / c.best_rank : 0)
|
|
813
|
+
};
|
|
814
|
+
}
|
|
815
|
+
function scoreSensorCase(name, expectFireIds, firedIds) {
|
|
816
|
+
const expect = uniq(expectFireIds);
|
|
817
|
+
const fired = uniq(firedIds);
|
|
818
|
+
const firedSet = new Set(fired);
|
|
819
|
+
const hits = expect.filter((id) => firedSet.has(id));
|
|
820
|
+
const misses = expect.filter((id) => !firedSet.has(id));
|
|
821
|
+
return {
|
|
822
|
+
name,
|
|
823
|
+
expect_fire_ids: expect,
|
|
824
|
+
fired_ids: fired,
|
|
825
|
+
hits,
|
|
826
|
+
misses,
|
|
827
|
+
recall: expect.length === 0 ? 1 : round32(hits.length / expect.length)
|
|
828
|
+
};
|
|
829
|
+
}
|
|
830
|
+
function aggregateSensors(cases) {
|
|
831
|
+
const totalExpected = cases.reduce((s, c) => s + c.expect_fire_ids.length, 0);
|
|
832
|
+
const totalHits = cases.reduce((s, c) => s + c.hits.length, 0);
|
|
833
|
+
return {
|
|
834
|
+
cases,
|
|
835
|
+
catch_rate: totalExpected === 0 ? 1 : round32(totalHits / totalExpected)
|
|
836
|
+
};
|
|
837
|
+
}
|
|
838
|
+
function overallScore(retrieval, sensors) {
|
|
839
|
+
if (retrieval && sensors) {
|
|
840
|
+
return Math.round((0.5 * retrieval.mean_recall + 0.2 * retrieval.mrr + 0.3 * sensors.catch_rate) * 100);
|
|
841
|
+
}
|
|
842
|
+
if (retrieval) {
|
|
843
|
+
return Math.round((0.7 * retrieval.mean_recall + 0.3 * retrieval.mrr) * 100);
|
|
844
|
+
}
|
|
845
|
+
if (sensors) {
|
|
846
|
+
return Math.round(sensors.catch_rate * 100);
|
|
847
|
+
}
|
|
848
|
+
return 0;
|
|
849
|
+
}
|
|
850
|
+
function buildReport(retrieval, sensors) {
|
|
851
|
+
return { retrieval, sensors, score: overallScore(retrieval, sensors) };
|
|
852
|
+
}
|
|
853
|
+
function titleFromBody(body) {
|
|
854
|
+
const lines = body.split("\n");
|
|
855
|
+
for (const line of lines) {
|
|
856
|
+
const heading = /^#+\s*(.+)$/.exec(line.trim());
|
|
857
|
+
if (heading) return heading[1].trim().slice(0, 120);
|
|
858
|
+
}
|
|
859
|
+
for (const line of lines) {
|
|
860
|
+
const t = line.trim();
|
|
861
|
+
if (t) return t.replace(/^[-*]\s*/, "").slice(0, 120);
|
|
862
|
+
}
|
|
863
|
+
return "";
|
|
864
|
+
}
|
|
865
|
+
function synthesizeSelfEvalCases(memories, options = {}) {
|
|
866
|
+
const includeFiles = options.includeFiles ?? true;
|
|
867
|
+
const skip = new Set(options.skipStatuses ?? ["stale", "deprecated", "rejected"]);
|
|
868
|
+
const cases = [];
|
|
869
|
+
for (const { memory } of memories) {
|
|
870
|
+
const fm = memory.frontmatter;
|
|
871
|
+
if (fm.type === "session_recap") continue;
|
|
872
|
+
if (skip.has(fm.status)) continue;
|
|
873
|
+
const paths = fm.anchor.paths;
|
|
874
|
+
if (paths.length === 0) continue;
|
|
875
|
+
const task = titleFromBody(memory.body) || fm.id;
|
|
876
|
+
cases.push({
|
|
877
|
+
name: fm.id,
|
|
878
|
+
task,
|
|
879
|
+
...includeFiles ? { files: paths } : {},
|
|
880
|
+
expect_ids: [fm.id]
|
|
881
|
+
});
|
|
882
|
+
}
|
|
883
|
+
return cases;
|
|
884
|
+
}
|
|
885
|
+
|
|
660
886
|
// src/confidence.ts
|
|
661
887
|
var DEFAULT_CONFIDENCE_THRESHOLDS = {
|
|
662
888
|
trustedReads: 3,
|
|
@@ -664,13 +890,13 @@ var DEFAULT_CONFIDENCE_THRESHOLDS = {
|
|
|
664
890
|
decayDays: 180,
|
|
665
891
|
hardDecayDays: 365
|
|
666
892
|
};
|
|
667
|
-
var
|
|
893
|
+
var MS_PER_DAY2 = 24 * 60 * 60 * 1e3;
|
|
668
894
|
function deriveConfidence(fm, usage, thresholds = DEFAULT_CONFIDENCE_THRESHOLDS, now = /* @__PURE__ */ new Date()) {
|
|
669
895
|
if (fm.status === "stale" || fm.status === "deprecated" || fm.status === "rejected") return "stale";
|
|
670
896
|
const baseLevel = baseConfidence(fm, usage, thresholds);
|
|
671
897
|
if (baseLevel !== "authoritative" && baseLevel !== "trusted") return baseLevel;
|
|
672
898
|
const anchor = usage.last_read_at ?? fm.created_at;
|
|
673
|
-
const ageDays = (now.getTime() - new Date(anchor).getTime()) /
|
|
899
|
+
const ageDays = (now.getTime() - new Date(anchor).getTime()) / MS_PER_DAY2;
|
|
674
900
|
if (Number.isNaN(ageDays) || ageDays <= 0) return baseLevel;
|
|
675
901
|
if (ageDays >= thresholds.hardDecayDays) {
|
|
676
902
|
return "low";
|
|
@@ -700,6 +926,43 @@ function isAutoPromoteEligible(fm, usage, rule = DEFAULT_AUTO_PROMOTE_RULE) {
|
|
|
700
926
|
return usage.read_count >= rule.minReads;
|
|
701
927
|
}
|
|
702
928
|
|
|
929
|
+
// src/skill-activation.ts
|
|
930
|
+
function isSkill(fm) {
|
|
931
|
+
return fm.type === "skill";
|
|
932
|
+
}
|
|
933
|
+
function evaluateSkillActivation(fm, ctx) {
|
|
934
|
+
if (!isSkill(fm)) return { applicable: false, activated: true, reasons: [] };
|
|
935
|
+
const act = fm.activation;
|
|
936
|
+
if (!act) return { applicable: false, activated: true, reasons: ["no-activation"] };
|
|
937
|
+
const reasons = [];
|
|
938
|
+
if (act.always) reasons.push("always");
|
|
939
|
+
const task = (ctx.task ?? "").toLowerCase();
|
|
940
|
+
if (task) {
|
|
941
|
+
for (const kw of act.keywords) {
|
|
942
|
+
if (kw && task.includes(kw.toLowerCase())) {
|
|
943
|
+
reasons.push(`keyword:${kw}`);
|
|
944
|
+
break;
|
|
945
|
+
}
|
|
946
|
+
}
|
|
947
|
+
}
|
|
948
|
+
const files = ctx.files ?? [];
|
|
949
|
+
if (files.length > 0) {
|
|
950
|
+
outer: for (const glob of act.globs) {
|
|
951
|
+
for (const f of files) {
|
|
952
|
+
if (pathsOverlap(glob, f)) {
|
|
953
|
+
reasons.push(`glob:${glob}`);
|
|
954
|
+
break outer;
|
|
955
|
+
}
|
|
956
|
+
}
|
|
957
|
+
}
|
|
958
|
+
}
|
|
959
|
+
return { applicable: true, activated: reasons.length > 0, reasons };
|
|
960
|
+
}
|
|
961
|
+
function isSkillSuppressed(fm, ctx) {
|
|
962
|
+
const result = evaluateSkillActivation(fm, ctx);
|
|
963
|
+
return result.applicable && !result.activated;
|
|
964
|
+
}
|
|
965
|
+
|
|
703
966
|
// src/specificity.ts
|
|
704
967
|
var GENERIC_PHRASES = [
|
|
705
968
|
"validate input",
|
|
@@ -2716,6 +2979,7 @@ function escapeRegExp(value) {
|
|
|
2716
2979
|
}
|
|
2717
2980
|
export {
|
|
2718
2981
|
AUTOPILOT_DEFAULTS,
|
|
2982
|
+
ActivationSchema,
|
|
2719
2983
|
AnchorSchema,
|
|
2720
2984
|
BRIEFING_MARKER_TTL_MS,
|
|
2721
2985
|
BRIEFING_PRESET_DEFAULTS,
|
|
@@ -2727,6 +2991,7 @@ export {
|
|
|
2727
2991
|
DEFAULT_AUTO_PROMOTE_RULE,
|
|
2728
2992
|
DEFAULT_CONFIDENCE_THRESHOLDS,
|
|
2729
2993
|
DEFAULT_CONFIG,
|
|
2994
|
+
DEFAULT_DORMANT_DAYS,
|
|
2730
2995
|
GUESSABLE_THRESHOLD,
|
|
2731
2996
|
HAIVE_DIR,
|
|
2732
2997
|
MEMORIES_DIR,
|
|
@@ -2743,6 +3008,8 @@ export {
|
|
|
2743
3008
|
USAGE_LOG_DIR,
|
|
2744
3009
|
USAGE_LOG_FILE,
|
|
2745
3010
|
addedLinesFromDiff,
|
|
3011
|
+
aggregateRetrieval,
|
|
3012
|
+
aggregateSensors,
|
|
2746
3013
|
aggregateUsage,
|
|
2747
3014
|
allocateBudget,
|
|
2748
3015
|
antiPatternGateParams,
|
|
@@ -2752,10 +3019,13 @@ export {
|
|
|
2752
3019
|
briefingMarkersDir,
|
|
2753
3020
|
buildCodeMap,
|
|
2754
3021
|
buildFrontmatter,
|
|
3022
|
+
buildReport,
|
|
2755
3023
|
bumpRead,
|
|
2756
3024
|
codeMapPath,
|
|
2757
3025
|
collectTimelineEntries,
|
|
3026
|
+
compareImpact,
|
|
2758
3027
|
compileRegexSensor,
|
|
3028
|
+
computeImpact,
|
|
2759
3029
|
configPath,
|
|
2760
3030
|
contractLockPath,
|
|
2761
3031
|
deriveConfidence,
|
|
@@ -2764,6 +3034,7 @@ export {
|
|
|
2764
3034
|
emptyUsageIndex,
|
|
2765
3035
|
enforcementDir,
|
|
2766
3036
|
estimateTokens,
|
|
3037
|
+
evaluateSkillActivation,
|
|
2767
3038
|
extractActionsBriefBody,
|
|
2768
3039
|
extractSnippet,
|
|
2769
3040
|
findLexicalConflictPairs,
|
|
@@ -2780,6 +3051,8 @@ export {
|
|
|
2780
3051
|
isGlobPath,
|
|
2781
3052
|
isLikelyGuessable,
|
|
2782
3053
|
isRetiredMemory,
|
|
3054
|
+
isSkill,
|
|
3055
|
+
isSkillSuppressed,
|
|
2783
3056
|
isStackPackSeed,
|
|
2784
3057
|
listMarkdownFilesRecursive,
|
|
2785
3058
|
literalMatchesAllTokens,
|
|
@@ -2794,6 +3067,7 @@ export {
|
|
|
2794
3067
|
memoryMatchesAnchorPaths,
|
|
2795
3068
|
newMemoryId,
|
|
2796
3069
|
normalizeSessionId,
|
|
3070
|
+
overallScore,
|
|
2797
3071
|
parseMemory,
|
|
2798
3072
|
parseSince,
|
|
2799
3073
|
pathsOverlap,
|
|
@@ -2804,6 +3078,7 @@ export {
|
|
|
2804
3078
|
readRecentBriefingMarker,
|
|
2805
3079
|
readRuntimeJournalTail,
|
|
2806
3080
|
readUsageEvents,
|
|
3081
|
+
recordApplied,
|
|
2807
3082
|
recordRejection,
|
|
2808
3083
|
relPathFrom,
|
|
2809
3084
|
resolveBriefingBudget,
|
|
@@ -2817,6 +3092,8 @@ export {
|
|
|
2817
3092
|
saveCodeMap,
|
|
2818
3093
|
saveConfig,
|
|
2819
3094
|
saveUsageIndex,
|
|
3095
|
+
scoreRetrievalCase,
|
|
3096
|
+
scoreSensorCase,
|
|
2820
3097
|
sensorAppliesToPath,
|
|
2821
3098
|
sensorTargetsFromDiff,
|
|
2822
3099
|
serializeMemory,
|
|
@@ -2825,6 +3102,9 @@ export {
|
|
|
2825
3102
|
stripPrivate,
|
|
2826
3103
|
suggestSensorFromMemory,
|
|
2827
3104
|
suggestTopicKey,
|
|
3105
|
+
summarizeImpact,
|
|
3106
|
+
synthesizeSelfEvalCases,
|
|
3107
|
+
titleFromBody,
|
|
2828
3108
|
tokenizeQuery,
|
|
2829
3109
|
trackDependencies,
|
|
2830
3110
|
trackReads,
|