0xray 4.0.21 → 4.0.23
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/.grok-plugin/plugin.json +1 -1
- package/.opencode/skills/hermes-agent/SKILL.md +1 -1
- package/.opencode/skills/orchestrator/SKILL.md +28 -6
- package/.xray/features.json +1 -1
- package/AGENTS-consumer.md +11 -11
- package/AGENTS.md +8 -8
- package/README.md +27 -27
- package/SKILLS.md +1 -1
- package/dist/AGENTS.md +8 -8
- package/dist/CHANGELOG.md +98 -0
- package/dist/README.md +27 -27
- package/dist/SKILLS.md +1 -1
- package/dist/governance/governance-core.d.ts +2 -1
- package/dist/governance/governance-core.js +20 -11
- package/dist/governance/governance-service.js +9 -7
- package/dist/inference/inference-accumulator.js +36 -4
- package/dist/inference/inference-cycle.d.ts +12 -0
- package/dist/inference/inference-cycle.js +180 -21
- package/dist/inference/inference-proposal-generator.js +148 -5
- package/dist/inference/session-capture.d.ts +4 -0
- package/dist/integrations/cursor/README.md +1 -1
- package/dist/integrations/cursor/hooks/cursor-hook-utils.js +19 -0
- package/dist/integrations/cursor/hooks/pre-tool-use.js +2 -1
- package/dist/integrations/governance/index.d.ts +5 -0
- package/dist/integrations/governance/index.js +22 -2
- package/dist/integrations/governance/types.d.ts +11 -0
- package/dist/integrations/governance/types.js +16 -0
- package/dist/integrations/hooks/station-hook-runtime.cjs +90 -30
- package/dist/integrations/hooks/station-hook-runtime.mjs +1 -0
- package/dist/integrations/hooks/station-memory-ingest.mjs +4 -2
- package/dist/integrations/openclaw/plugin/xray-pre-tool/package.json +1 -1
- package/dist/mcps/governance.server.d.ts +2 -0
- package/dist/mcps/governance.server.js +12 -1
- package/dist/memory-routing/index.d.ts +1 -1
- package/dist/memory-routing/index.js +1 -1
- package/dist/memory-routing/lesson-pickup.d.ts +2 -0
- package/dist/memory-routing/lesson-pickup.js +57 -0
- package/dist/memory-routing/provider-loader.d.ts +8 -1
- package/dist/memory-routing/provider-loader.js +49 -1
- package/dist/memory-routing/provider-registry.d.ts +7 -2
- package/dist/memory-routing/provider-registry.js +26 -6
- package/dist/memory-routing/record-lesson.d.ts +16 -0
- package/dist/memory-routing/record-lesson.js +26 -0
- package/dist/memory-routing/types.d.ts +15 -0
- package/dist/nucleus/thin-dispatch.d.ts +2 -0
- package/dist/nucleus/thin-dispatch.js +14 -4
- package/dist/processors/implementations/agents-md-validation-processor.js +1 -1
- package/dist/skills/hermes-agent/SKILL.md +1 -1
- package/dist/skills/orchestrator/SKILL.md +28 -6
- package/package.json +2 -2
- package/scripts/foundry/CHANGELOG.md +2 -0
- package/scripts/foundry/README.md +2 -2
- package/scripts/foundry/cli.mjs +1 -1
- package/scripts/foundry/inspect.mjs +160 -5
- package/scripts/foundry/plant/skills/inspect/SKILL.md +2 -0
- package/scripts/foundry/reconcile-version.mjs +23 -1
- package/scripts/foundry/release.mjs +1 -1
- package/scripts/foundry/validate-release-docs.mjs +24 -20
- package/scripts/foundry/version-manager.mjs +180 -7
- package/scripts/mjs/test-consumer-readiness.mjs +10 -3
- package/src/integrations/openclaw/plugin/xray-pre-tool/package.json +1 -1
- package/src/mcps/governance.server.ts +12 -1
- package/src/skills/hermes-agent/SKILL.md +1 -1
- package/src/skills/orchestrator/SKILL.md +28 -6
- package/vendor/@0xray/repertoire/data/stack-overlay.json +156 -3
- package/vendor/@0xray/repertoire/data/subject-overlay.json +3 -3
- package/vendor/@0xray/repertoire/dist/RepertoireService.d.ts +4 -0
- package/vendor/@0xray/repertoire/dist/RepertoireService.d.ts.map +1 -1
- package/vendor/@0xray/repertoire/dist/RepertoireService.js +7 -6
- package/vendor/@0xray/repertoire/dist/RepertoireService.js.map +1 -1
- package/vendor/@0xray/repertoire/dist/ingestion/xray-session-ingester.d.ts.map +1 -1
- package/vendor/@0xray/repertoire/dist/ingestion/xray-session-ingester.js +10 -11
- package/vendor/@0xray/repertoire/dist/ingestion/xray-session-ingester.js.map +1 -1
- package/vendor/@0xray/repertoire/dist/orchestrator-bridge/confidence-gate.d.ts.map +1 -1
- package/vendor/@0xray/repertoire/dist/orchestrator-bridge/confidence-gate.js +5 -0
- package/vendor/@0xray/repertoire/dist/orchestrator-bridge/confidence-gate.js.map +1 -1
- package/vendor/@0xray/repertoire/dist/orchestrator-bridge/signal-injector.d.ts.map +1 -1
- package/vendor/@0xray/repertoire/dist/orchestrator-bridge/signal-injector.js +16 -0
- package/vendor/@0xray/repertoire/dist/orchestrator-bridge/signal-injector.js.map +1 -1
- package/vendor/@0xray/repertoire/dist/paths.d.ts +3 -3
- package/vendor/@0xray/repertoire/dist/paths.d.ts.map +1 -1
- package/vendor/@0xray/repertoire/dist/paths.js +66 -4
- package/vendor/@0xray/repertoire/dist/paths.js.map +1 -1
- package/vendor/@0xray/repertoire/dist/provider/memory-routing-provider.d.ts +11 -0
- package/vendor/@0xray/repertoire/dist/provider/memory-routing-provider.d.ts.map +1 -1
- package/vendor/@0xray/repertoire/dist/provider/memory-routing-provider.js +2 -0
- package/vendor/@0xray/repertoire/dist/provider/memory-routing-provider.js.map +1 -1
- package/vendor/@0xray/repertoire/dist/registry/CuratedSignalsManager.d.ts +54 -4
- package/vendor/@0xray/repertoire/dist/registry/CuratedSignalsManager.d.ts.map +1 -1
- package/vendor/@0xray/repertoire/dist/registry/CuratedSignalsManager.js +375 -20
- package/vendor/@0xray/repertoire/dist/registry/CuratedSignalsManager.js.map +1 -1
- package/vendor/@0xray/repertoire/dist/types.d.ts +21 -0
- package/vendor/@0xray/repertoire/dist/types.d.ts.map +1 -1
- package/xray/agents_template.md +10 -5
- package/xray/features.json +1 -1
- package/dist/mcps/shared/prompt-security-validator.d.ts +0 -44
- package/dist/mcps/shared/prompt-security-validator.js +0 -148
- package/dist/mcps/shared/security-scanner.d.ts +0 -119
- package/dist/mcps/shared/security-scanner.js +0 -429
- package/dist/scripts/activate-kernel-pipeline.d.ts +0 -7
- package/dist/scripts/activate-kernel-pipeline.js +0 -101
- package/src/mcps/shared/prompt-security-validator.ts +0 -199
- package/src/mcps/shared/security-scanner.ts +0 -599
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memory-routing-provider.js","sourceRoot":"","sources":["../../src/provider/memory-routing-provider.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACpB,sBAAsB,EACtB,yBAAyB,EACzB,yBAAyB,GAC1B,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"memory-routing-provider.js","sourceRoot":"","sources":["../../src/provider/memory-routing-provider.ts"],"names":[],"mappings":"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"}
|
|
@@ -8,9 +8,31 @@ export interface PromotionGateOptions {
|
|
|
8
8
|
}
|
|
9
9
|
export declare const DEFAULT_PROMOTION_MIN_CONFIDENCE = 0.55;
|
|
10
10
|
export declare const DEFAULT_PROMOTION_MIN_OBSERVATIONS = 2;
|
|
11
|
-
|
|
12
|
-
export declare const
|
|
13
|
-
export declare const
|
|
11
|
+
/** One outcome moves routing. A 0.002 nudge on a floor average does not. */
|
|
12
|
+
export declare const FEEDBACK_SUCCESS_CONFIDENCE_BOOST = 0.1;
|
|
13
|
+
export declare const FEEDBACK_FAILURE_CONFIDENCE_PENALTY = 0.1;
|
|
14
|
+
/** Failure may drop below the promotion gate so the law leaves the next decision. */
|
|
15
|
+
export declare const FEEDBACK_MIN_CONFIDENCE = 0;
|
|
16
|
+
/** Consecutive definition content words that count as a paraphrase of the law. */
|
|
17
|
+
export declare const LAW_CLAUSE_SPAN = 4;
|
|
18
|
+
export declare function isConfidenceFloor(value: number, gate?: number): boolean;
|
|
19
|
+
export declare function clauseTokens(text: string): string[];
|
|
20
|
+
/**
|
|
21
|
+
* A paraphrase is four consecutive definition content words, in order, inside a
|
|
22
|
+
* short query window (twice the clause). Two stray words are not a clause.
|
|
23
|
+
* The same words scattered through a long diary are not a clause.
|
|
24
|
+
*/
|
|
25
|
+
export declare function lawClauseInText(definition: string, text: string, span?: number): boolean;
|
|
26
|
+
export declare function isAboveConfidenceFloor(value: number, gate?: number): boolean;
|
|
27
|
+
/** Hot lines kept on a law. Older lines leave only after their task id is in the ledger. */
|
|
28
|
+
export declare const LESSON_LINE_CAP = 20;
|
|
29
|
+
export declare const LESSON_TEXT_CAP = 400;
|
|
30
|
+
/**
|
|
31
|
+
* The diary names a law only when it contains the signal id, or the id with
|
|
32
|
+
* hyphens read as spaces. A repo tail, leftover tokens, and two definition
|
|
33
|
+
* words are not the name.
|
|
34
|
+
*/
|
|
35
|
+
export declare function signalNameInText(text: string, name: string): boolean;
|
|
14
36
|
/** Enriched JSONL names only — not June heading dumps (`phase-3-…`, `7-final-statement`). */
|
|
15
37
|
export declare function isFieldPrimitiveName(name: string): boolean;
|
|
16
38
|
/** Slug a session/pattern/package label into a dest name, or null. */
|
|
@@ -27,6 +49,7 @@ export interface FeedbackOutcomeResult {
|
|
|
27
49
|
export declare class CuratedSignalsManager {
|
|
28
50
|
readonly filePath: string;
|
|
29
51
|
constructor(filePath?: string);
|
|
52
|
+
learnedConvictionPath(): string;
|
|
30
53
|
load(): CuratedSignalsFile;
|
|
31
54
|
save(data: CuratedSignalsFile): void;
|
|
32
55
|
/**
|
|
@@ -40,10 +63,17 @@ export declare class CuratedSignalsManager {
|
|
|
40
63
|
getHighPrioritySignals(): CuratedSignal[];
|
|
41
64
|
getByPriority(priority: SignalPriority): CuratedSignal[];
|
|
42
65
|
/**
|
|
43
|
-
* Score text against
|
|
66
|
+
* Score text against signals. A hit is the signal id, the id with hyphens
|
|
67
|
+
* read as spaces, or a consecutive definition clause. Two definition words
|
|
68
|
+
* are not a match.
|
|
44
69
|
*/
|
|
45
70
|
matchByText(text: string, minScore?: number): SignalMatch[];
|
|
46
71
|
matchInferenceEntry(inference: string): SignalMatch[];
|
|
72
|
+
/**
|
|
73
|
+
* Mark names the diary already matched. Does not append a confidence sample.
|
|
74
|
+
* Missing names are left absent. Heat must not mint a law.
|
|
75
|
+
*/
|
|
76
|
+
touchLastSeen(names: string[]): string[];
|
|
47
77
|
recordPrimitiveObservations(matches: PrimitiveMatch[], options?: {
|
|
48
78
|
governanceForced?: boolean;
|
|
49
79
|
minConfidence?: number;
|
|
@@ -61,6 +91,26 @@ export declare class CuratedSignalsManager {
|
|
|
61
91
|
* Successful outcomes nudge avg_confidence up slightly; failures nudge down.
|
|
62
92
|
*/
|
|
63
93
|
recordFeedbackOutcome(entry: OrchestratorFeedbackEntry): FeedbackOutcomeResult[];
|
|
94
|
+
/**
|
|
95
|
+
* Append one graded line. A task id already on the law, or already aged into
|
|
96
|
+
* the ledger, does not move the average and does not append again.
|
|
97
|
+
* Past the cap, the oldest line leaves only after its id is in the ledger.
|
|
98
|
+
*/
|
|
99
|
+
private rememberLesson;
|
|
100
|
+
/**
|
|
101
|
+
* Conviction that left the 0.55 floor. Not the observation counter.
|
|
102
|
+
* Graded lines sit beside the average. A wake that copies the overlay floor
|
|
103
|
+
* back onto dest restores both.
|
|
104
|
+
*/
|
|
105
|
+
private writeLearnedConviction;
|
|
106
|
+
/**
|
|
107
|
+
* Averages already above the floor survive a flatten even when no new
|
|
108
|
+
* feedback has run. Floor names, including float dust at 0.55, stay out.
|
|
109
|
+
*/
|
|
110
|
+
private seedLearnedConviction;
|
|
111
|
+
private readLearnedConvictionFile;
|
|
112
|
+
private writeLearnedConvictionFile;
|
|
113
|
+
restoreLearnedConviction(): string[];
|
|
64
114
|
private createEmptyFile;
|
|
65
115
|
}
|
|
66
116
|
//# sourceMappingURL=CuratedSignalsManager.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CuratedSignalsManager.d.ts","sourceRoot":"","sources":["../../src/registry/CuratedSignalsManager.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"CuratedSignalsManager.d.ts","sourceRoot":"","sources":["../../src/registry/CuratedSignalsManager.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,12 +1,137 @@
|
|
|
1
1
|
import { readFileSync, writeFileSync, existsSync } from 'node:fs';
|
|
2
|
+
import { dirname, join } from 'node:path';
|
|
2
3
|
import { DEFAULT_SIGNALS_PATH, hydrateWritableSignals, isFactorySeedFile, isGenericFieldObservedDefinition, } from '../paths.js';
|
|
3
4
|
import { effectiveSignalConfidence, shouldDemoteValidatedSignal, } from './confidence-decay.js';
|
|
4
5
|
export const DEFAULT_PROMOTION_MIN_CONFIDENCE = 0.55;
|
|
5
6
|
export const DEFAULT_PROMOTION_MIN_OBSERVATIONS = 2;
|
|
6
|
-
|
|
7
|
-
export const
|
|
8
|
-
export const
|
|
7
|
+
/** One outcome moves routing. A 0.002 nudge on a floor average does not. */
|
|
8
|
+
export const FEEDBACK_SUCCESS_CONFIDENCE_BOOST = 0.1;
|
|
9
|
+
export const FEEDBACK_FAILURE_CONFIDENCE_PENALTY = 0.1;
|
|
10
|
+
/** Failure may drop below the promotion gate so the law leaves the next decision. */
|
|
11
|
+
export const FEEDBACK_MIN_CONFIDENCE = 0;
|
|
12
|
+
/** Consecutive definition content words that count as a paraphrase of the law. */
|
|
13
|
+
export const LAW_CLAUSE_SPAN = 4;
|
|
14
|
+
const LEARNED_CONVICTION_FILE = 'learned-conviction.json';
|
|
15
|
+
const CLAUSE_STOP = new Set([
|
|
16
|
+
'a', 'an', 'the', 'only', 'just', 'not', 'never', 'always', 'and', 'or', 'of', 'to', 'for',
|
|
17
|
+
'on', 'in', 'with', 'from', 'by', 'is', 'are', 'be', 'this', 'that', 'it', 'as', 'at', 'do',
|
|
18
|
+
'does', 'into', 'than', 'then', 'so', 'if', 'but', 'its', 'their', 'was', 'were',
|
|
19
|
+
]);
|
|
20
|
+
export function isConfidenceFloor(value, gate = DEFAULT_PROMOTION_MIN_CONFIDENCE) {
|
|
21
|
+
return Math.abs(value - gate) <= 1e-4;
|
|
22
|
+
}
|
|
23
|
+
export function clauseTokens(text) {
|
|
24
|
+
return text
|
|
25
|
+
.toLowerCase()
|
|
26
|
+
.split(/[^a-z0-9]+/)
|
|
27
|
+
.filter((word) => word.length >= 3 && !CLAUSE_STOP.has(word));
|
|
28
|
+
}
|
|
29
|
+
function isSubsequence(window, query) {
|
|
30
|
+
let index = 0;
|
|
31
|
+
for (const word of window) {
|
|
32
|
+
while (index < query.length && query[index] !== word)
|
|
33
|
+
index += 1;
|
|
34
|
+
if (index >= query.length)
|
|
35
|
+
return false;
|
|
36
|
+
index += 1;
|
|
37
|
+
}
|
|
38
|
+
return true;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* A paraphrase is four consecutive definition content words, in order, inside a
|
|
42
|
+
* short query window (twice the clause). Two stray words are not a clause.
|
|
43
|
+
* The same words scattered through a long diary are not a clause.
|
|
44
|
+
*/
|
|
45
|
+
export function lawClauseInText(definition, text, span = LAW_CLAUSE_SPAN) {
|
|
46
|
+
const law = clauseTokens(definition);
|
|
47
|
+
const query = clauseTokens(text);
|
|
48
|
+
if (law.length < span || query.length < span)
|
|
49
|
+
return false;
|
|
50
|
+
const room = span * 2;
|
|
51
|
+
for (let start = 0; start + span <= law.length; start += 1) {
|
|
52
|
+
const window = law.slice(start, start + span);
|
|
53
|
+
for (let at = 0; at < query.length; at += 1) {
|
|
54
|
+
const slice = query.slice(at, at + room);
|
|
55
|
+
if (slice.length < span)
|
|
56
|
+
break;
|
|
57
|
+
if (isSubsequence(window, slice))
|
|
58
|
+
return true;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return false;
|
|
62
|
+
}
|
|
63
|
+
function evidenceWeight(previous, gate) {
|
|
64
|
+
if (!previous)
|
|
65
|
+
return 0;
|
|
66
|
+
if (typeof previous.evidence_count === 'number')
|
|
67
|
+
return previous.evidence_count;
|
|
68
|
+
if (previous.avg_confidence > gate + 1e-4)
|
|
69
|
+
return previous.observation_count;
|
|
70
|
+
return 0;
|
|
71
|
+
}
|
|
72
|
+
/** Historical averages with no counter still count as one piece of evidence. */
|
|
73
|
+
function seededEvidenceCount(evidence) {
|
|
74
|
+
return typeof evidence === 'number' && evidence > 0 ? evidence : 1;
|
|
75
|
+
}
|
|
76
|
+
function validLessons(value) {
|
|
77
|
+
if (!Array.isArray(value))
|
|
78
|
+
return [];
|
|
79
|
+
const lessons = [];
|
|
80
|
+
for (const item of value) {
|
|
81
|
+
if (!item || typeof item !== 'object')
|
|
82
|
+
continue;
|
|
83
|
+
const row = item;
|
|
84
|
+
if (typeof row.taskId !== 'string' || row.taskId.length === 0)
|
|
85
|
+
continue;
|
|
86
|
+
if (row.decision !== 'success' && row.decision !== 'failure')
|
|
87
|
+
continue;
|
|
88
|
+
if (typeof row.text !== 'string' || typeof row.at !== 'string')
|
|
89
|
+
continue;
|
|
90
|
+
lessons.push({ taskId: row.taskId, decision: row.decision, text: row.text, at: row.at });
|
|
91
|
+
}
|
|
92
|
+
return lessons;
|
|
93
|
+
}
|
|
94
|
+
function validLessonIds(value) {
|
|
95
|
+
if (!Array.isArray(value))
|
|
96
|
+
return [];
|
|
97
|
+
return value.filter((item) => typeof item === 'string' && item.length > 0);
|
|
98
|
+
}
|
|
99
|
+
function convictionRecord(stats, signal, prior) {
|
|
100
|
+
const lessons = signal.lessons?.length ? signal.lessons : prior?.lessons;
|
|
101
|
+
const retained = signal.retained_lesson_ids?.length ? signal.retained_lesson_ids : prior?.retained_lesson_ids;
|
|
102
|
+
const row = {
|
|
103
|
+
avg_confidence: stats.avg_confidence,
|
|
104
|
+
evidence_count: seededEvidenceCount(stats.evidence_count),
|
|
105
|
+
updated_at: stats.last_seen,
|
|
106
|
+
};
|
|
107
|
+
if (lessons?.length)
|
|
108
|
+
row.lessons = lessons;
|
|
109
|
+
if (retained?.length)
|
|
110
|
+
row.retained_lesson_ids = retained;
|
|
111
|
+
return row;
|
|
112
|
+
}
|
|
113
|
+
export function isAboveConfidenceFloor(value, gate = DEFAULT_PROMOTION_MIN_CONFIDENCE) {
|
|
114
|
+
return value > gate && !isConfidenceFloor(value, gate);
|
|
115
|
+
}
|
|
116
|
+
/** Hot lines kept on a law. Older lines leave only after their task id is in the ledger. */
|
|
117
|
+
export const LESSON_LINE_CAP = 20;
|
|
118
|
+
export const LESSON_TEXT_CAP = 400;
|
|
9
119
|
const FIELD_PRIMITIVE_NAME = /^[A-Za-z][A-Za-z0-9_-]{2,119}$/;
|
|
120
|
+
/**
|
|
121
|
+
* The diary names a law only when it contains the signal id, or the id with
|
|
122
|
+
* hyphens read as spaces. A repo tail, leftover tokens, and two definition
|
|
123
|
+
* words are not the name.
|
|
124
|
+
*/
|
|
125
|
+
export function signalNameInText(text, name) {
|
|
126
|
+
const normalized = text.toLowerCase();
|
|
127
|
+
const id = name.toLowerCase();
|
|
128
|
+
if (!id)
|
|
129
|
+
return false;
|
|
130
|
+
if (normalized.includes(id))
|
|
131
|
+
return true;
|
|
132
|
+
const spaced = id.replace(/-/g, ' ');
|
|
133
|
+
return spaced !== id && normalized.includes(spaced);
|
|
134
|
+
}
|
|
10
135
|
const GROOVER_EXPERIMENT_NAMES = new Set([
|
|
11
136
|
'criteria_selection_gap',
|
|
12
137
|
'external_norm_smuggling_risk',
|
|
@@ -67,6 +192,11 @@ export class CuratedSignalsManager {
|
|
|
67
192
|
filePath;
|
|
68
193
|
constructor(filePath) {
|
|
69
194
|
this.filePath = filePath ?? hydrateWritableSignals(DEFAULT_SIGNALS_PATH);
|
|
195
|
+
this.restoreLearnedConviction();
|
|
196
|
+
this.seedLearnedConviction();
|
|
197
|
+
}
|
|
198
|
+
learnedConvictionPath() {
|
|
199
|
+
return join(dirname(this.filePath), LEARNED_CONVICTION_FILE);
|
|
70
200
|
}
|
|
71
201
|
load() {
|
|
72
202
|
if (!existsSync(this.filePath)) {
|
|
@@ -119,25 +249,20 @@ export class CuratedSignalsManager {
|
|
|
119
249
|
return this.load().signals.filter((s) => s.priority === priority);
|
|
120
250
|
}
|
|
121
251
|
/**
|
|
122
|
-
* Score text against
|
|
252
|
+
* Score text against signals. A hit is the signal id, the id with hyphens
|
|
253
|
+
* read as spaces, or a consecutive definition clause. Two definition words
|
|
254
|
+
* are not a match.
|
|
123
255
|
*/
|
|
124
256
|
matchByText(text, minScore = 2) {
|
|
125
257
|
const normalized = text.toLowerCase();
|
|
126
258
|
const matches = [];
|
|
127
259
|
for (const signal of this.load().signals) {
|
|
128
|
-
const
|
|
129
|
-
|
|
130
|
-
if (
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
else if (signal.name.startsWith('repo-')) {
|
|
135
|
-
const tail = signal.name.slice(5);
|
|
136
|
-
if (tail.length >= 3 && new RegExp(`\\b${tail}\\b`, 'i').test(normalized)) {
|
|
137
|
-
score += 5;
|
|
138
|
-
matchedOn.push('name');
|
|
139
|
-
}
|
|
140
|
-
}
|
|
260
|
+
const named = signalNameInText(text, signal.name);
|
|
261
|
+
const clause = !named && lawClauseInText(signal.definition, text);
|
|
262
|
+
if (!named && !clause)
|
|
263
|
+
continue;
|
|
264
|
+
const matchedOn = named ? ['name'] : ['definition'];
|
|
265
|
+
let score = named ? 5 : 4;
|
|
141
266
|
for (const tag of signal.tags) {
|
|
142
267
|
if (normalized.includes(tag.toLowerCase())) {
|
|
143
268
|
score += 3;
|
|
@@ -191,6 +316,39 @@ export class CuratedSignalsManager {
|
|
|
191
316
|
}
|
|
192
317
|
return matches.sort((a, b) => b.score - a.score);
|
|
193
318
|
}
|
|
319
|
+
/**
|
|
320
|
+
* Mark names the diary already matched. Does not append a confidence sample.
|
|
321
|
+
* Missing names are left absent. Heat must not mint a law.
|
|
322
|
+
*/
|
|
323
|
+
touchLastSeen(names) {
|
|
324
|
+
const data = this.load();
|
|
325
|
+
const now = new Date().toISOString();
|
|
326
|
+
const updated = [];
|
|
327
|
+
const seen = new Set();
|
|
328
|
+
for (const name of names) {
|
|
329
|
+
if (!name || seen.has(name))
|
|
330
|
+
continue;
|
|
331
|
+
seen.add(name);
|
|
332
|
+
const signal = data.signals.find((entry) => entry.name === name);
|
|
333
|
+
if (!signal)
|
|
334
|
+
continue;
|
|
335
|
+
const previous = signal.observation_stats;
|
|
336
|
+
signal.observation_stats = previous
|
|
337
|
+
? { ...previous, last_seen: now }
|
|
338
|
+
: {
|
|
339
|
+
observation_count: 0,
|
|
340
|
+
avg_confidence: 0,
|
|
341
|
+
max_confidence: 0,
|
|
342
|
+
last_seen: now,
|
|
343
|
+
governance_forced_count: 0,
|
|
344
|
+
};
|
|
345
|
+
updated.push(signal.name);
|
|
346
|
+
}
|
|
347
|
+
if (updated.length > 0) {
|
|
348
|
+
this.save(data);
|
|
349
|
+
}
|
|
350
|
+
return updated;
|
|
351
|
+
}
|
|
194
352
|
recordPrimitiveObservations(matches, options = {}) {
|
|
195
353
|
const minConfidence = options.minConfidence ?? DEFAULT_PROMOTION_MIN_CONFIDENCE;
|
|
196
354
|
const data = this.load();
|
|
@@ -208,13 +366,38 @@ export class CuratedSignalsManager {
|
|
|
208
366
|
}
|
|
209
367
|
const previous = signal.observation_stats;
|
|
210
368
|
const observationCount = (previous?.observation_count ?? 0) + 1;
|
|
211
|
-
const
|
|
369
|
+
const forced = (previous?.governance_forced_count ?? 0) + (options.governanceForced ? 1 : 0);
|
|
370
|
+
const atFloor = isConfidenceFloor(match.confidence, minConfidence);
|
|
371
|
+
if (atFloor) {
|
|
372
|
+
signal.observation_stats = previous
|
|
373
|
+
? {
|
|
374
|
+
...previous,
|
|
375
|
+
observation_count: observationCount,
|
|
376
|
+
last_seen: now,
|
|
377
|
+
governance_forced_count: forced,
|
|
378
|
+
evidence_count: evidenceWeight(previous, minConfidence),
|
|
379
|
+
}
|
|
380
|
+
: {
|
|
381
|
+
observation_count: observationCount,
|
|
382
|
+
avg_confidence: match.confidence,
|
|
383
|
+
max_confidence: match.confidence,
|
|
384
|
+
last_seen: now,
|
|
385
|
+
governance_forced_count: forced,
|
|
386
|
+
evidence_count: 0,
|
|
387
|
+
};
|
|
388
|
+
updated.push(signal.name);
|
|
389
|
+
continue;
|
|
390
|
+
}
|
|
391
|
+
const weight = evidenceWeight(previous, minConfidence);
|
|
392
|
+
const evidenceCount = weight + 1;
|
|
393
|
+
const priorAvg = weight > 0 && previous ? previous.avg_confidence : 0;
|
|
212
394
|
signal.observation_stats = {
|
|
213
395
|
observation_count: observationCount,
|
|
214
|
-
avg_confidence:
|
|
396
|
+
avg_confidence: (priorAvg * weight + match.confidence) / evidenceCount,
|
|
215
397
|
max_confidence: Math.max(previous?.max_confidence ?? 0, match.confidence),
|
|
216
398
|
last_seen: now,
|
|
217
|
-
governance_forced_count:
|
|
399
|
+
governance_forced_count: forced,
|
|
400
|
+
evidence_count: evidenceCount,
|
|
218
401
|
};
|
|
219
402
|
updated.push(signal.name);
|
|
220
403
|
}
|
|
@@ -286,6 +469,15 @@ export class CuratedSignalsManager {
|
|
|
286
469
|
const signal = data.signals.find((candidate) => candidate.name === signalName);
|
|
287
470
|
if (!signal)
|
|
288
471
|
continue;
|
|
472
|
+
const lessonText = typeof entry.lesson === 'string' ? entry.lesson.trim().slice(0, LESSON_TEXT_CAP) : '';
|
|
473
|
+
if (this.rememberLesson(signal, {
|
|
474
|
+
taskId: entry.taskId,
|
|
475
|
+
decision: entry.success ? 'success' : 'failure',
|
|
476
|
+
text: lessonText,
|
|
477
|
+
at: now,
|
|
478
|
+
}) === 'already') {
|
|
479
|
+
continue;
|
|
480
|
+
}
|
|
289
481
|
const previousAvg = signal.observation_stats?.avg_confidence ?? null;
|
|
290
482
|
const previousFeedback = signal.feedback_stats;
|
|
291
483
|
const outcomeCount = (previousFeedback?.outcome_count ?? 0) + 1;
|
|
@@ -304,11 +496,14 @@ export class CuratedSignalsManager {
|
|
|
304
496
|
? FEEDBACK_SUCCESS_CONFIDENCE_BOOST
|
|
305
497
|
: -FEEDBACK_FAILURE_CONFIDENCE_PENALTY;
|
|
306
498
|
const next = Math.max(FEEDBACK_MIN_CONFIDENCE, Math.min(1, signal.observation_stats.avg_confidence + delta));
|
|
499
|
+
const weight = evidenceWeight(signal.observation_stats, DEFAULT_PROMOTION_MIN_CONFIDENCE);
|
|
307
500
|
signal.observation_stats = {
|
|
308
501
|
...signal.observation_stats,
|
|
309
502
|
avg_confidence: next,
|
|
503
|
+
evidence_count: weight > 0 ? weight : 1,
|
|
310
504
|
last_seen: now,
|
|
311
505
|
};
|
|
506
|
+
this.writeLearnedConviction(signal.name, signal.observation_stats, signal);
|
|
312
507
|
}
|
|
313
508
|
results.push({
|
|
314
509
|
signalName,
|
|
@@ -322,6 +517,166 @@ export class CuratedSignalsManager {
|
|
|
322
517
|
}
|
|
323
518
|
return results;
|
|
324
519
|
}
|
|
520
|
+
/**
|
|
521
|
+
* Append one graded line. A task id already on the law, or already aged into
|
|
522
|
+
* the ledger, does not move the average and does not append again.
|
|
523
|
+
* Past the cap, the oldest line leaves only after its id is in the ledger.
|
|
524
|
+
*/
|
|
525
|
+
rememberLesson(signal, line) {
|
|
526
|
+
if (!line.taskId)
|
|
527
|
+
return 'already';
|
|
528
|
+
const lessons = [...(signal.lessons ?? [])];
|
|
529
|
+
const retained = new Set(signal.retained_lesson_ids ?? []);
|
|
530
|
+
if (lessons.some((stored) => stored.taskId === line.taskId) || retained.has(line.taskId)) {
|
|
531
|
+
return 'already';
|
|
532
|
+
}
|
|
533
|
+
lessons.push(line);
|
|
534
|
+
const overflow = lessons.length - LESSON_LINE_CAP;
|
|
535
|
+
if (overflow > 0) {
|
|
536
|
+
for (const aged of lessons.splice(0, overflow))
|
|
537
|
+
retained.add(aged.taskId);
|
|
538
|
+
}
|
|
539
|
+
signal.lessons = lessons;
|
|
540
|
+
if (retained.size > 0)
|
|
541
|
+
signal.retained_lesson_ids = [...retained].sort();
|
|
542
|
+
return 'stored';
|
|
543
|
+
}
|
|
544
|
+
/**
|
|
545
|
+
* Conviction that left the 0.55 floor. Not the observation counter.
|
|
546
|
+
* Graded lines sit beside the average. A wake that copies the overlay floor
|
|
547
|
+
* back onto dest restores both.
|
|
548
|
+
*/
|
|
549
|
+
writeLearnedConviction(name, stats, signal) {
|
|
550
|
+
if (isFactorySeedFile(this.filePath))
|
|
551
|
+
return;
|
|
552
|
+
const file = this.readLearnedConvictionFile();
|
|
553
|
+
file.signals[name] = convictionRecord(stats, signal, file.signals[name]);
|
|
554
|
+
this.writeLearnedConvictionFile(file);
|
|
555
|
+
}
|
|
556
|
+
/**
|
|
557
|
+
* Averages already above the floor survive a flatten even when no new
|
|
558
|
+
* feedback has run. Floor names, including float dust at 0.55, stay out.
|
|
559
|
+
*/
|
|
560
|
+
seedLearnedConviction() {
|
|
561
|
+
if (isFactorySeedFile(this.filePath) || !existsSync(this.filePath))
|
|
562
|
+
return [];
|
|
563
|
+
const data = this.load();
|
|
564
|
+
const learned = this.readLearnedConvictionFile();
|
|
565
|
+
const seeded = [];
|
|
566
|
+
let destDirty = false;
|
|
567
|
+
for (const signal of data.signals) {
|
|
568
|
+
const stats = signal.observation_stats;
|
|
569
|
+
if (!stats || !isAboveConfidenceFloor(stats.avg_confidence))
|
|
570
|
+
continue;
|
|
571
|
+
const evidence = seededEvidenceCount(stats.evidence_count);
|
|
572
|
+
if (stats.evidence_count !== evidence) {
|
|
573
|
+
signal.observation_stats = { ...stats, evidence_count: evidence };
|
|
574
|
+
destDirty = true;
|
|
575
|
+
}
|
|
576
|
+
const current = signal.observation_stats;
|
|
577
|
+
if (!current)
|
|
578
|
+
continue;
|
|
579
|
+
const row = learned.signals[signal.name];
|
|
580
|
+
const rowAvg = row && typeof row.avg_confidence === 'number' ? row.avg_confidence : undefined;
|
|
581
|
+
const missing = rowAvg === undefined;
|
|
582
|
+
const higher = rowAvg !== undefined && current.avg_confidence > rowAvg + 1e-4;
|
|
583
|
+
const rowEvidence = row && typeof row.evidence_count === 'number' && row.evidence_count > 0
|
|
584
|
+
? row.evidence_count
|
|
585
|
+
: undefined;
|
|
586
|
+
const nextLessons = signal.lessons?.length ? signal.lessons : validLessons(row?.lessons);
|
|
587
|
+
const nextRetained = signal.retained_lesson_ids?.length
|
|
588
|
+
? signal.retained_lesson_ids
|
|
589
|
+
: validLessonIds(row?.retained_lesson_ids);
|
|
590
|
+
const sameLessons = JSON.stringify(nextLessons) === JSON.stringify(validLessons(row?.lessons));
|
|
591
|
+
const sameRetained = JSON.stringify(nextRetained) === JSON.stringify(validLessonIds(row?.retained_lesson_ids));
|
|
592
|
+
if (!missing && !higher && rowEvidence !== undefined && sameLessons && sameRetained)
|
|
593
|
+
continue;
|
|
594
|
+
const keptAvg = !missing && !higher && rowAvg !== undefined ? rowAvg : current.avg_confidence;
|
|
595
|
+
learned.signals[signal.name] = convictionRecord({ ...current, avg_confidence: keptAvg }, { lessons: nextLessons, retained_lesson_ids: nextRetained });
|
|
596
|
+
seeded.push(signal.name);
|
|
597
|
+
}
|
|
598
|
+
if (seeded.length > 0)
|
|
599
|
+
this.writeLearnedConvictionFile(learned);
|
|
600
|
+
if (destDirty)
|
|
601
|
+
this.save(data);
|
|
602
|
+
return seeded;
|
|
603
|
+
}
|
|
604
|
+
readLearnedConvictionFile() {
|
|
605
|
+
const empty = { schema_version: '1', signals: {} };
|
|
606
|
+
const path = this.learnedConvictionPath();
|
|
607
|
+
if (!existsSync(path))
|
|
608
|
+
return empty;
|
|
609
|
+
try {
|
|
610
|
+
const parsed = JSON.parse(readFileSync(path, 'utf8'));
|
|
611
|
+
if (parsed &&
|
|
612
|
+
parsed.signals &&
|
|
613
|
+
typeof parsed.signals === 'object' &&
|
|
614
|
+
!Array.isArray(parsed.signals)) {
|
|
615
|
+
return { schema_version: '1', signals: parsed.signals };
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
catch {
|
|
619
|
+
return empty;
|
|
620
|
+
}
|
|
621
|
+
return empty;
|
|
622
|
+
}
|
|
623
|
+
writeLearnedConvictionFile(file) {
|
|
624
|
+
const body = { schema_version: '1', signals: file.signals };
|
|
625
|
+
writeFileSync(this.learnedConvictionPath(), `${JSON.stringify(body, null, 2)}\n`);
|
|
626
|
+
}
|
|
627
|
+
restoreLearnedConviction() {
|
|
628
|
+
if (isFactorySeedFile(this.filePath) || !existsSync(this.filePath))
|
|
629
|
+
return [];
|
|
630
|
+
const path = this.learnedConvictionPath();
|
|
631
|
+
if (!existsSync(path))
|
|
632
|
+
return [];
|
|
633
|
+
let learned;
|
|
634
|
+
try {
|
|
635
|
+
learned = JSON.parse(readFileSync(path, 'utf8'));
|
|
636
|
+
}
|
|
637
|
+
catch {
|
|
638
|
+
return [];
|
|
639
|
+
}
|
|
640
|
+
if (!learned?.signals || typeof learned.signals !== 'object' || Array.isArray(learned.signals)) {
|
|
641
|
+
return [];
|
|
642
|
+
}
|
|
643
|
+
const data = this.load();
|
|
644
|
+
const restored = [];
|
|
645
|
+
for (const [name, row] of Object.entries(learned.signals)) {
|
|
646
|
+
if (!row || typeof row.avg_confidence !== 'number')
|
|
647
|
+
continue;
|
|
648
|
+
if (isConfidenceFloor(row.avg_confidence))
|
|
649
|
+
continue;
|
|
650
|
+
const signal = data.signals.find((entry) => entry.name === name);
|
|
651
|
+
const stats = signal?.observation_stats;
|
|
652
|
+
if (!signal || !stats)
|
|
653
|
+
continue;
|
|
654
|
+
const learnedLessons = validLessons(row.lessons);
|
|
655
|
+
const learnedIds = validLessonIds(row.retained_lesson_ids);
|
|
656
|
+
const avgOnFloor = isConfidenceFloor(stats.avg_confidence);
|
|
657
|
+
const destHasLessons = (signal.lessons?.length ?? 0) > 0;
|
|
658
|
+
if (!avgOnFloor && destHasLessons)
|
|
659
|
+
continue;
|
|
660
|
+
if (!avgOnFloor && learnedLessons.length === 0 && learnedIds.length === 0)
|
|
661
|
+
continue;
|
|
662
|
+
if (avgOnFloor) {
|
|
663
|
+
signal.observation_stats = {
|
|
664
|
+
...stats,
|
|
665
|
+
avg_confidence: row.avg_confidence,
|
|
666
|
+
evidence_count: typeof row.evidence_count === 'number' ? row.evidence_count : stats.evidence_count,
|
|
667
|
+
};
|
|
668
|
+
}
|
|
669
|
+
if (!destHasLessons && learnedLessons.length > 0)
|
|
670
|
+
signal.lessons = learnedLessons;
|
|
671
|
+
if ((signal.retained_lesson_ids?.length ?? 0) === 0 && learnedIds.length > 0) {
|
|
672
|
+
signal.retained_lesson_ids = learnedIds;
|
|
673
|
+
}
|
|
674
|
+
restored.push(name);
|
|
675
|
+
}
|
|
676
|
+
if (restored.length > 0)
|
|
677
|
+
this.save(data);
|
|
678
|
+
return restored;
|
|
679
|
+
}
|
|
325
680
|
createEmptyFile() {
|
|
326
681
|
return {
|
|
327
682
|
description: 'Curated high-signal primitives for Repertoire',
|