@aiassesstech/jessie 0.5.1 → 0.6.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/agent/AGENTS.md +14 -1
- package/agent/SOUL.md +16 -0
- package/dist/command/decision-store.d.ts +4 -1
- package/dist/command/decision-store.d.ts.map +1 -1
- package/dist/command/decision-store.js +28 -0
- package/dist/command/decision-store.js.map +1 -1
- package/dist/command/types.d.ts +14 -1
- package/dist/command/types.d.ts.map +1 -1
- package/dist/command/types.js +4 -6
- package/dist/command/types.js.map +1 -1
- package/dist/ea/calendar-conflicts.d.ts +30 -0
- package/dist/ea/calendar-conflicts.d.ts.map +1 -0
- package/dist/ea/calendar-conflicts.js +70 -0
- package/dist/ea/calendar-conflicts.js.map +1 -0
- package/dist/ea/correspondence-client.d.ts +54 -0
- package/dist/ea/correspondence-client.d.ts.map +1 -0
- package/dist/ea/correspondence-client.js +88 -0
- package/dist/ea/correspondence-client.js.map +1 -0
- package/dist/ea/daily-notes.d.ts +38 -0
- package/dist/ea/daily-notes.d.ts.map +1 -0
- package/dist/ea/daily-notes.js +93 -0
- package/dist/ea/daily-notes.js.map +1 -0
- package/dist/ea/ea-sweep.d.ts +49 -0
- package/dist/ea/ea-sweep.d.ts.map +1 -0
- package/dist/ea/ea-sweep.js +93 -0
- package/dist/ea/ea-sweep.js.map +1 -0
- package/dist/ea/fleet-attention-gate.d.ts +33 -0
- package/dist/ea/fleet-attention-gate.d.ts.map +1 -0
- package/dist/ea/fleet-attention-gate.js +46 -0
- package/dist/ea/fleet-attention-gate.js.map +1 -0
- package/dist/ea/gog-health.d.ts +34 -0
- package/dist/ea/gog-health.d.ts.map +1 -0
- package/dist/ea/gog-health.js +68 -0
- package/dist/ea/gog-health.js.map +1 -0
- package/dist/ea/index.d.ts +19 -0
- package/dist/ea/index.d.ts.map +1 -0
- package/dist/ea/index.js +13 -0
- package/dist/ea/index.js.map +1 -0
- package/dist/ea/sweep-state.d.ts +53 -0
- package/dist/ea/sweep-state.d.ts.map +1 -0
- package/dist/ea/sweep-state.js +145 -0
- package/dist/ea/sweep-state.js.map +1 -0
- package/dist/knowledge/knowledge-store.d.ts +62 -0
- package/dist/knowledge/knowledge-store.d.ts.map +1 -0
- package/dist/knowledge/knowledge-store.js +248 -0
- package/dist/knowledge/knowledge-store.js.map +1 -0
- package/dist/knowledge/provenance.d.ts +16 -0
- package/dist/knowledge/provenance.d.ts.map +1 -0
- package/dist/knowledge/provenance.js +23 -0
- package/dist/knowledge/provenance.js.map +1 -0
- package/dist/knowledge/verify-provenance.d.ts +17 -0
- package/dist/knowledge/verify-provenance.d.ts.map +1 -0
- package/dist/knowledge/verify-provenance.js +38 -0
- package/dist/knowledge/verify-provenance.js.map +1 -0
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +203 -2
- package/dist/plugin.js.map +1 -1
- package/dist/tools/fleet-memory-search.d.ts +87 -0
- package/dist/tools/fleet-memory-search.d.ts.map +1 -0
- package/dist/tools/fleet-memory-search.js +73 -0
- package/dist/tools/fleet-memory-search.js.map +1 -0
- package/dist/tools/fleet-snapshot.d.ts +63 -0
- package/dist/tools/fleet-snapshot.d.ts.map +1 -0
- package/dist/tools/fleet-snapshot.js +137 -0
- package/dist/tools/fleet-snapshot.js.map +1 -0
- package/dist/tools/jessie-briefing.d.ts.map +1 -1
- package/dist/tools/jessie-briefing.js +1 -0
- package/dist/tools/jessie-briefing.js.map +1 -1
- package/dist/tools/jessie-decide.js +2 -2
- package/dist/tools/jessie-decide.js.map +1 -1
- package/dist/tools/jessie-delegate.js +1 -1
- package/dist/tools/jessie-delegate.js.map +1 -1
- package/dist/tools/jessie-wiki.d.ts +76 -0
- package/dist/tools/jessie-wiki.d.ts.map +1 -0
- package/dist/tools/jessie-wiki.js +197 -0
- package/dist/tools/jessie-wiki.js.map +1 -0
- package/openclaw.plugin.json +40 -9
- package/package.json +2 -2
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* EA Sweep State — Persistence & Deduplication
|
|
3
|
+
*
|
|
4
|
+
* SPEC: SPEC-jessie-executive-assistant-activation-v1.0 §3.1, IH2
|
|
5
|
+
*
|
|
6
|
+
* Tracks processed message IDs to prevent re-processing, triage
|
|
7
|
+
* statistics, Grillo assessment counts, and sweep metadata.
|
|
8
|
+
* Persists to .jessie-data/ea-sweep-state.json.
|
|
9
|
+
*/
|
|
10
|
+
import * as fs from 'node:fs';
|
|
11
|
+
import * as path from 'node:path';
|
|
12
|
+
const DEFAULT_STATS = {
|
|
13
|
+
autoResolved: 0,
|
|
14
|
+
escalated: 0,
|
|
15
|
+
archived: 0,
|
|
16
|
+
tasksCreated: 0,
|
|
17
|
+
grilloAssessments: {
|
|
18
|
+
green: 0,
|
|
19
|
+
yellow: 0,
|
|
20
|
+
red: 0,
|
|
21
|
+
recuse: 0,
|
|
22
|
+
unavailable: 0,
|
|
23
|
+
degraded: false,
|
|
24
|
+
consecutiveTimeouts: 0,
|
|
25
|
+
lastAssessmentHash: '',
|
|
26
|
+
lastRubricVersion: '',
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
const MAX_MESSAGE_AGE_MS = 7 * 24 * 60 * 60 * 1000;
|
|
30
|
+
export class EaSweepState {
|
|
31
|
+
data;
|
|
32
|
+
filePath;
|
|
33
|
+
constructor(dataDir) {
|
|
34
|
+
this.filePath = path.join(dataDir, 'ea-sweep-state.json');
|
|
35
|
+
this.data = this.load();
|
|
36
|
+
}
|
|
37
|
+
get state() {
|
|
38
|
+
return this.data;
|
|
39
|
+
}
|
|
40
|
+
isProcessed(messageId) {
|
|
41
|
+
return this.data.processedMessageIds.includes(messageId);
|
|
42
|
+
}
|
|
43
|
+
markProcessed(messageId) {
|
|
44
|
+
if (!this.data.processedMessageIds.includes(messageId)) {
|
|
45
|
+
this.data.processedMessageIds.push(messageId);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
recordSweep(stats) {
|
|
49
|
+
this.data.lastSweepAt = new Date().toISOString();
|
|
50
|
+
if (stats.autoResolved)
|
|
51
|
+
this.data.triageStats.autoResolved += stats.autoResolved;
|
|
52
|
+
if (stats.escalated)
|
|
53
|
+
this.data.triageStats.escalated += stats.escalated;
|
|
54
|
+
if (stats.archived)
|
|
55
|
+
this.data.triageStats.archived += stats.archived;
|
|
56
|
+
if (stats.tasksCreated)
|
|
57
|
+
this.data.triageStats.tasksCreated += stats.tasksCreated;
|
|
58
|
+
}
|
|
59
|
+
recordGrilloAssessment(verdict, assessmentHash, rubricVersion) {
|
|
60
|
+
const ga = this.data.triageStats.grilloAssessments;
|
|
61
|
+
ga[verdict]++;
|
|
62
|
+
if (verdict === 'unavailable') {
|
|
63
|
+
ga.consecutiveTimeouts++;
|
|
64
|
+
if (ga.consecutiveTimeouts >= 2) {
|
|
65
|
+
ga.degraded = true;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
ga.consecutiveTimeouts = 0;
|
|
70
|
+
ga.degraded = false;
|
|
71
|
+
}
|
|
72
|
+
if (assessmentHash)
|
|
73
|
+
ga.lastAssessmentHash = assessmentHash;
|
|
74
|
+
if (rubricVersion)
|
|
75
|
+
ga.lastRubricVersion = rubricVersion;
|
|
76
|
+
}
|
|
77
|
+
setGogHealthy(healthy) {
|
|
78
|
+
this.data.gogHealthy = healthy;
|
|
79
|
+
}
|
|
80
|
+
setFleetDeferred(deferred, reason) {
|
|
81
|
+
this.data.fleetAttentionDeferred = deferred;
|
|
82
|
+
this.data.lastDeferralReason = reason;
|
|
83
|
+
}
|
|
84
|
+
isGrilloDegraded() {
|
|
85
|
+
return this.data.triageStats.grilloAssessments.degraded;
|
|
86
|
+
}
|
|
87
|
+
clearGrilloDegraded() {
|
|
88
|
+
this.data.triageStats.grilloAssessments.degraded = false;
|
|
89
|
+
this.data.triageStats.grilloAssessments.consecutiveTimeouts = 0;
|
|
90
|
+
}
|
|
91
|
+
pruneOldMessages() {
|
|
92
|
+
const cutoff = Date.now() - MAX_MESSAGE_AGE_MS;
|
|
93
|
+
const before = this.data.processedMessageIds.length;
|
|
94
|
+
this.data.processedMessageIds = this.data.processedMessageIds.filter((id) => {
|
|
95
|
+
const ts = parseInt(id.split('_').pop() ?? '0', 10);
|
|
96
|
+
return isNaN(ts) || ts > cutoff;
|
|
97
|
+
});
|
|
98
|
+
if (this.data.processedMessageIds.length < before) {
|
|
99
|
+
console.log(`[jessie:ea] Pruned ${before - this.data.processedMessageIds.length} old message IDs`);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
save() {
|
|
103
|
+
const dir = path.dirname(this.filePath);
|
|
104
|
+
if (!fs.existsSync(dir)) {
|
|
105
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
106
|
+
}
|
|
107
|
+
const tmp = this.filePath + '.tmp';
|
|
108
|
+
fs.writeFileSync(tmp, JSON.stringify(this.data, null, 2), 'utf-8');
|
|
109
|
+
fs.renameSync(tmp, this.filePath);
|
|
110
|
+
}
|
|
111
|
+
load() {
|
|
112
|
+
try {
|
|
113
|
+
if (fs.existsSync(this.filePath)) {
|
|
114
|
+
const raw = fs.readFileSync(this.filePath, 'utf-8');
|
|
115
|
+
const parsed = JSON.parse(raw);
|
|
116
|
+
return {
|
|
117
|
+
lastSweepAt: parsed.lastSweepAt ?? null,
|
|
118
|
+
processedMessageIds: parsed.processedMessageIds ?? [],
|
|
119
|
+
triageStats: {
|
|
120
|
+
...DEFAULT_STATS,
|
|
121
|
+
...(parsed.triageStats ?? {}),
|
|
122
|
+
grilloAssessments: {
|
|
123
|
+
...DEFAULT_STATS.grilloAssessments,
|
|
124
|
+
...(parsed.triageStats?.grilloAssessments ?? {}),
|
|
125
|
+
},
|
|
126
|
+
},
|
|
127
|
+
gogHealthy: parsed.gogHealthy ?? true,
|
|
128
|
+
fleetAttentionDeferred: parsed.fleetAttentionDeferred ?? false,
|
|
129
|
+
lastDeferralReason: parsed.lastDeferralReason,
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
catch {
|
|
134
|
+
console.warn('[jessie:ea] Failed to load sweep state, starting fresh');
|
|
135
|
+
}
|
|
136
|
+
return {
|
|
137
|
+
lastSweepAt: null,
|
|
138
|
+
processedMessageIds: [],
|
|
139
|
+
triageStats: { ...DEFAULT_STATS, grilloAssessments: { ...DEFAULT_STATS.grilloAssessments } },
|
|
140
|
+
gogHealthy: true,
|
|
141
|
+
fleetAttentionDeferred: false,
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
//# sourceMappingURL=sweep-state.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sweep-state.js","sourceRoot":"","sources":["../../src/ea/sweep-state.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Jessie Knowledge Store — Compounding Fleet Intelligence
|
|
3
|
+
*
|
|
4
|
+
* SPEC-fleet-knowledge-base-v1.2 §3.2.3:
|
|
5
|
+
* Manages wiki/ directory within Jessie's workspace. All articles have
|
|
6
|
+
* cryptographic provenance via SHA-256 hash chains. Write operations use
|
|
7
|
+
* atomic temp-file → rename pattern (IH1) to avoid hashless windows.
|
|
8
|
+
*
|
|
9
|
+
* Write operations are executed by Sam via the compilation pipeline.
|
|
10
|
+
* KnowledgeStore itself is the persistence layer — it does not call LLMs.
|
|
11
|
+
*/
|
|
12
|
+
import type { SourceReference } from './provenance.js';
|
|
13
|
+
import type { WikiCategory } from '@aiassesstech/fleet-bus';
|
|
14
|
+
export interface WikiArticle {
|
|
15
|
+
slug: string;
|
|
16
|
+
title: string;
|
|
17
|
+
category: WikiCategory;
|
|
18
|
+
lastUpdated: string;
|
|
19
|
+
tags: string[];
|
|
20
|
+
summary: string;
|
|
21
|
+
sources: SourceReference[];
|
|
22
|
+
contentHash: string;
|
|
23
|
+
compilationEvent: string;
|
|
24
|
+
derivedRatio: number;
|
|
25
|
+
}
|
|
26
|
+
export interface WikiIndex {
|
|
27
|
+
version: number;
|
|
28
|
+
lastCompiled: string;
|
|
29
|
+
lastHealthCheck: string | null;
|
|
30
|
+
articles: WikiArticle[];
|
|
31
|
+
totalArticles: number;
|
|
32
|
+
}
|
|
33
|
+
export declare class KnowledgeStore {
|
|
34
|
+
readonly wikiDir: string;
|
|
35
|
+
readonly outputsDir: string;
|
|
36
|
+
readonly archiveDir: string;
|
|
37
|
+
readonly baseDir: string;
|
|
38
|
+
private readonly indexPath;
|
|
39
|
+
private index;
|
|
40
|
+
constructor(workspaceDir: string);
|
|
41
|
+
initialize(): Promise<void>;
|
|
42
|
+
getIndex(): WikiIndex;
|
|
43
|
+
getArticle(slug: string): WikiArticle | null;
|
|
44
|
+
getArticleContent(slug: string): string | null;
|
|
45
|
+
getArticleContentHash(slug: string): string | null;
|
|
46
|
+
listArticles(): WikiArticle[];
|
|
47
|
+
writeArticle(slug: string, content: string, meta: Omit<WikiArticle, 'slug' | 'contentHash' | 'derivedRatio'>): WikiArticle;
|
|
48
|
+
saveOutput(filename: string, content: string, expiresInDays?: number): string;
|
|
49
|
+
getStaleArticlesByCategory(defaults: Record<string, number>, overrides?: Record<string, number>): WikiArticle[];
|
|
50
|
+
getHighDerivedArticles(threshold?: number): WikiArticle[];
|
|
51
|
+
archiveExpiredOutputs(): string[];
|
|
52
|
+
recordHealthCheck(): void;
|
|
53
|
+
writeProbeArticle(slug: string, content: string): void;
|
|
54
|
+
readProbeArticle(slug: string): string | null;
|
|
55
|
+
deleteProbeArticle(slug: string): boolean;
|
|
56
|
+
private resolveArticlePath;
|
|
57
|
+
private updateIndexEntry;
|
|
58
|
+
private createEmptyIndex;
|
|
59
|
+
private parseIndex;
|
|
60
|
+
private writeIndex;
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=knowledge-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"knowledge-store.d.ts","sourceRoot":"","sources":["../../src/knowledge/knowledge-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAKH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAE5D,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,YAAY,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,eAAe,EAAE,CAAC;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,EAAE,MAAM,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,qBAAa,cAAc;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,KAAK,CAAY;gBAEb,YAAY,EAAE,MAAM;IAS1B,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAmBjC,QAAQ,IAAI,SAAS;IAIrB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI;IAI5C,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAM9C,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAUlD,YAAY,IAAI,WAAW,EAAE;IAI7B,YAAY,CACV,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,IAAI,CAAC,WAAW,EAAE,MAAM,GAAG,aAAa,GAAG,cAAc,CAAC,GAC/D,WAAW;IAqDd,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,aAAa,SAAK,GAAG,MAAM;IAkBzE,0BAA0B,CACxB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAChC,SAAS,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,GACrC,WAAW,EAAE;IAUhB,sBAAsB,CAAC,SAAS,SAAM,GAAG,WAAW,EAAE;IAItD,qBAAqB,IAAI,MAAM,EAAE;IAkCjC,iBAAiB,IAAI,IAAI;IAKzB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI;IAKtD,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAM7C,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAOzC,OAAO,CAAC,kBAAkB;IAI1B,OAAO,CAAC,gBAAgB;IAYxB,OAAO,CAAC,gBAAgB;IAUxB,OAAO,CAAC,UAAU;IASlB,OAAO,CAAC,UAAU;CA0BnB"}
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Jessie Knowledge Store — Compounding Fleet Intelligence
|
|
3
|
+
*
|
|
4
|
+
* SPEC-fleet-knowledge-base-v1.2 §3.2.3:
|
|
5
|
+
* Manages wiki/ directory within Jessie's workspace. All articles have
|
|
6
|
+
* cryptographic provenance via SHA-256 hash chains. Write operations use
|
|
7
|
+
* atomic temp-file → rename pattern (IH1) to avoid hashless windows.
|
|
8
|
+
*
|
|
9
|
+
* Write operations are executed by Sam via the compilation pipeline.
|
|
10
|
+
* KnowledgeStore itself is the persistence layer — it does not call LLMs.
|
|
11
|
+
*/
|
|
12
|
+
import * as fs from 'node:fs';
|
|
13
|
+
import * as path from 'node:path';
|
|
14
|
+
import { computeContentHash } from './provenance.js';
|
|
15
|
+
export class KnowledgeStore {
|
|
16
|
+
wikiDir;
|
|
17
|
+
outputsDir;
|
|
18
|
+
archiveDir;
|
|
19
|
+
baseDir;
|
|
20
|
+
indexPath;
|
|
21
|
+
index;
|
|
22
|
+
constructor(workspaceDir) {
|
|
23
|
+
this.baseDir = workspaceDir;
|
|
24
|
+
this.wikiDir = path.join(workspaceDir, 'wiki');
|
|
25
|
+
this.outputsDir = path.join(workspaceDir, 'outputs');
|
|
26
|
+
this.archiveDir = path.join(this.outputsDir, 'archive');
|
|
27
|
+
this.indexPath = path.join(this.wikiDir, 'INDEX.md');
|
|
28
|
+
this.index = this.createEmptyIndex();
|
|
29
|
+
}
|
|
30
|
+
async initialize() {
|
|
31
|
+
for (const dir of [
|
|
32
|
+
this.wikiDir,
|
|
33
|
+
this.outputsDir,
|
|
34
|
+
this.archiveDir,
|
|
35
|
+
path.join(this.wikiDir, '.probes'),
|
|
36
|
+
]) {
|
|
37
|
+
if (!fs.existsSync(dir)) {
|
|
38
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
if (fs.existsSync(this.indexPath)) {
|
|
42
|
+
this.index = this.parseIndex();
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
this.writeIndex();
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
getIndex() {
|
|
49
|
+
return this.index;
|
|
50
|
+
}
|
|
51
|
+
getArticle(slug) {
|
|
52
|
+
return this.index.articles.find(a => a.slug === slug) ?? null;
|
|
53
|
+
}
|
|
54
|
+
getArticleContent(slug) {
|
|
55
|
+
const articlePath = this.resolveArticlePath(slug);
|
|
56
|
+
if (!fs.existsSync(articlePath))
|
|
57
|
+
return null;
|
|
58
|
+
return fs.readFileSync(articlePath, 'utf-8');
|
|
59
|
+
}
|
|
60
|
+
getArticleContentHash(slug) {
|
|
61
|
+
const content = this.getArticleContent(slug);
|
|
62
|
+
if (!content)
|
|
63
|
+
return null;
|
|
64
|
+
// Strip the content_hash line before hashing — the hash was computed
|
|
65
|
+
// over the file content without this line (IH1: can't hash a string
|
|
66
|
+
// that contains its own hash).
|
|
67
|
+
const withoutHashLine = content.replace(/^content_hash:.*\n/m, '');
|
|
68
|
+
return computeContentHash(withoutHashLine);
|
|
69
|
+
}
|
|
70
|
+
listArticles() {
|
|
71
|
+
return this.index.articles.filter(a => !a.slug.startsWith('.probes/'));
|
|
72
|
+
}
|
|
73
|
+
writeArticle(slug, content, meta) {
|
|
74
|
+
const articlePath = this.resolveArticlePath(slug);
|
|
75
|
+
const dir = path.dirname(articlePath);
|
|
76
|
+
if (!fs.existsSync(dir)) {
|
|
77
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
78
|
+
}
|
|
79
|
+
const derivedCount = meta.sources.filter(s => s.type === 'derived').length;
|
|
80
|
+
const derivedRatio = meta.sources.length > 0
|
|
81
|
+
? derivedCount / meta.sources.length
|
|
82
|
+
: 0;
|
|
83
|
+
const frontmatterFields = [
|
|
84
|
+
'---',
|
|
85
|
+
`title: "${meta.title}"`,
|
|
86
|
+
`slug: "${slug}"`,
|
|
87
|
+
`category: "${meta.category}"`,
|
|
88
|
+
`updated: "${meta.lastUpdated}"`,
|
|
89
|
+
`tags: [${meta.tags.map(t => `"${t}"`).join(', ')}]`,
|
|
90
|
+
'sources:',
|
|
91
|
+
...meta.sources.map(s => ` - path: "${s.path}"\n sha256: "${s.sha256}"\n type: "${s.type}"`),
|
|
92
|
+
`compilation_event: "${meta.compilationEvent}"`,
|
|
93
|
+
];
|
|
94
|
+
// IH1: Compute content_hash over the complete file content deterministically
|
|
95
|
+
// before the first write. Avoids the hashless-window race with Mark's
|
|
96
|
+
// wiki-integrity check by using atomic write (temp file + rename).
|
|
97
|
+
const bodyWithFrontmatterNoHash = [...frontmatterFields, '---', ''].join('\n') + content;
|
|
98
|
+
const contentHash = computeContentHash(bodyWithFrontmatterNoHash);
|
|
99
|
+
const fullContent = [
|
|
100
|
+
...frontmatterFields,
|
|
101
|
+
`content_hash: "${contentHash}"`,
|
|
102
|
+
'---',
|
|
103
|
+
'',
|
|
104
|
+
].join('\n') + content;
|
|
105
|
+
const tmpPath = articlePath + `.tmp.${Date.now()}`;
|
|
106
|
+
fs.writeFileSync(tmpPath, fullContent);
|
|
107
|
+
fs.renameSync(tmpPath, articlePath);
|
|
108
|
+
const article = {
|
|
109
|
+
slug,
|
|
110
|
+
...meta,
|
|
111
|
+
contentHash,
|
|
112
|
+
derivedRatio,
|
|
113
|
+
};
|
|
114
|
+
this.updateIndexEntry(article);
|
|
115
|
+
return article;
|
|
116
|
+
}
|
|
117
|
+
saveOutput(filename, content, expiresInDays = 90) {
|
|
118
|
+
const outputPath = path.join(this.outputsDir, filename);
|
|
119
|
+
const expiresAt = new Date(Date.now() + expiresInDays * 24 * 60 * 60 * 1000).toISOString();
|
|
120
|
+
const frontmatter = [
|
|
121
|
+
'---',
|
|
122
|
+
`created: "${new Date().toISOString()}"`,
|
|
123
|
+
`expires_at: "${expiresAt}"`,
|
|
124
|
+
'---',
|
|
125
|
+
'',
|
|
126
|
+
].join('\n');
|
|
127
|
+
fs.writeFileSync(outputPath, frontmatter + content);
|
|
128
|
+
return outputPath;
|
|
129
|
+
}
|
|
130
|
+
getStaleArticlesByCategory(defaults, overrides = {}) {
|
|
131
|
+
const thresholds = { ...defaults, ...overrides };
|
|
132
|
+
return this.index.articles.filter(a => {
|
|
133
|
+
const maxDays = thresholds[a.category] ?? 14;
|
|
134
|
+
const ageDays = (Date.now() - new Date(a.lastUpdated).getTime())
|
|
135
|
+
/ (1000 * 60 * 60 * 24);
|
|
136
|
+
return ageDays > maxDays;
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
getHighDerivedArticles(threshold = 0.5) {
|
|
140
|
+
return this.index.articles.filter(a => a.derivedRatio > threshold);
|
|
141
|
+
}
|
|
142
|
+
archiveExpiredOutputs() {
|
|
143
|
+
const archived = [];
|
|
144
|
+
const now = Date.now();
|
|
145
|
+
let files;
|
|
146
|
+
try {
|
|
147
|
+
files = fs.readdirSync(this.outputsDir)
|
|
148
|
+
.filter(f => f.endsWith('.md') && f !== 'archive');
|
|
149
|
+
}
|
|
150
|
+
catch {
|
|
151
|
+
return archived;
|
|
152
|
+
}
|
|
153
|
+
for (const file of files) {
|
|
154
|
+
const filePath = path.join(this.outputsDir, file);
|
|
155
|
+
const content = fs.readFileSync(filePath, 'utf-8');
|
|
156
|
+
const expiresMatch = content.match(/expires_at:\s*"(.+?)"/);
|
|
157
|
+
if (expiresMatch) {
|
|
158
|
+
const expiresAt = new Date(expiresMatch[1]).getTime();
|
|
159
|
+
if (expiresAt < now) {
|
|
160
|
+
const monthDir = path.join(this.archiveDir, new Date().toISOString().slice(0, 7));
|
|
161
|
+
if (!fs.existsSync(monthDir)) {
|
|
162
|
+
fs.mkdirSync(monthDir, { recursive: true });
|
|
163
|
+
}
|
|
164
|
+
fs.renameSync(filePath, path.join(monthDir, file));
|
|
165
|
+
archived.push(file);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
return archived;
|
|
170
|
+
}
|
|
171
|
+
recordHealthCheck() {
|
|
172
|
+
this.index.lastHealthCheck = new Date().toISOString();
|
|
173
|
+
this.writeIndex();
|
|
174
|
+
}
|
|
175
|
+
writeProbeArticle(slug, content) {
|
|
176
|
+
const probePath = path.join(this.wikiDir, '.probes', `${slug}.md`);
|
|
177
|
+
fs.writeFileSync(probePath, content);
|
|
178
|
+
}
|
|
179
|
+
readProbeArticle(slug) {
|
|
180
|
+
const probePath = path.join(this.wikiDir, '.probes', `${slug}.md`);
|
|
181
|
+
if (!fs.existsSync(probePath))
|
|
182
|
+
return null;
|
|
183
|
+
return fs.readFileSync(probePath, 'utf-8');
|
|
184
|
+
}
|
|
185
|
+
deleteProbeArticle(slug) {
|
|
186
|
+
const probePath = path.join(this.wikiDir, '.probes', `${slug}.md`);
|
|
187
|
+
if (!fs.existsSync(probePath))
|
|
188
|
+
return false;
|
|
189
|
+
fs.unlinkSync(probePath);
|
|
190
|
+
return true;
|
|
191
|
+
}
|
|
192
|
+
resolveArticlePath(slug) {
|
|
193
|
+
return path.join(this.wikiDir, `${slug}.md`);
|
|
194
|
+
}
|
|
195
|
+
updateIndexEntry(article) {
|
|
196
|
+
const existing = this.index.articles.findIndex(a => a.slug === article.slug);
|
|
197
|
+
if (existing >= 0) {
|
|
198
|
+
this.index.articles[existing] = article;
|
|
199
|
+
}
|
|
200
|
+
else {
|
|
201
|
+
this.index.articles.push(article);
|
|
202
|
+
}
|
|
203
|
+
this.index.totalArticles = this.index.articles.length;
|
|
204
|
+
this.index.lastCompiled = new Date().toISOString();
|
|
205
|
+
this.writeIndex();
|
|
206
|
+
}
|
|
207
|
+
createEmptyIndex() {
|
|
208
|
+
return {
|
|
209
|
+
version: 1,
|
|
210
|
+
lastCompiled: new Date().toISOString(),
|
|
211
|
+
lastHealthCheck: null,
|
|
212
|
+
articles: [],
|
|
213
|
+
totalArticles: 0,
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
parseIndex() {
|
|
217
|
+
try {
|
|
218
|
+
const content = fs.readFileSync(this.indexPath, 'utf-8');
|
|
219
|
+
const jsonMatch = content.match(/```json\n([\s\S]*?)\n```/);
|
|
220
|
+
if (jsonMatch)
|
|
221
|
+
return JSON.parse(jsonMatch[1]);
|
|
222
|
+
}
|
|
223
|
+
catch { /* fall through */ }
|
|
224
|
+
return this.createEmptyIndex();
|
|
225
|
+
}
|
|
226
|
+
writeIndex() {
|
|
227
|
+
const visibleArticles = this.index.articles.filter(a => !a.slug.startsWith('.probes/'));
|
|
228
|
+
const content = [
|
|
229
|
+
'# Jessie Knowledge Base — Index',
|
|
230
|
+
'',
|
|
231
|
+
`Last compiled: ${this.index.lastCompiled}`,
|
|
232
|
+
`Last health check: ${this.index.lastHealthCheck ?? 'never'}`,
|
|
233
|
+
`Total articles: ${visibleArticles.length}`,
|
|
234
|
+
'',
|
|
235
|
+
'## Articles',
|
|
236
|
+
'',
|
|
237
|
+
...visibleArticles.map(a => `- **[[${a.slug}]]** — ${a.summary} *(${a.category}, updated: ${a.lastUpdated})*`),
|
|
238
|
+
'',
|
|
239
|
+
'## Machine-Readable Index',
|
|
240
|
+
'',
|
|
241
|
+
'```json',
|
|
242
|
+
JSON.stringify(this.index, null, 2),
|
|
243
|
+
'```',
|
|
244
|
+
].join('\n');
|
|
245
|
+
fs.writeFileSync(this.indexPath, content);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
//# sourceMappingURL=knowledge-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"knowledge-store.js","sourceRoot":"","sources":["../../src/knowledge/knowledge-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAyBrD,MAAM,OAAO,cAAc;IAChB,OAAO,CAAS;IAChB,UAAU,CAAS;IACnB,UAAU,CAAS;IACnB,OAAO,CAAS;IACR,SAAS,CAAS;IAC3B,KAAK,CAAY;IAEzB,YAAY,YAAoB;QAC9B,IAAI,CAAC,OAAO,GAAG,YAAY,CAAC;QAC5B,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;QAC/C,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,SAAS,CAAC,CAAC;QACrD,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;QACxD,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;QACrD,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,gBAAgB,EAAE,CAAC;IACvC,CAAC;IAED,KAAK,CAAC,UAAU;QACd,KAAK,MAAM,GAAG,IAAI;YAChB,IAAI,CAAC,OAAO;YACZ,IAAI,CAAC,UAAU;YACf,IAAI,CAAC,UAAU;YACf,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,CAAC;SACnC,EAAE,CAAC;YACF,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;gBACxB,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YACzC,CAAC;QACH,CAAC;QAED,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;YAClC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;QACjC,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,UAAU,EAAE,CAAC;QACpB,CAAC;IACH,CAAC;IAED,QAAQ;QACN,OAAO,IAAI,CAAC,KAAK,CAAC;IACpB,CAAC;IAED,UAAU,CAAC,IAAY;QACrB,OAAO,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,IAAI,CAAC;IAChE,CAAC;IAED,iBAAiB,CAAC,IAAY;QAC5B,MAAM,WAAW,GAAG,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC;QAClD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC;YAAE,OAAO,IAAI,CAAC;QAC7C,OAAO,EAAE,CAAC,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IAC/C,CAAC;IAED,qBAAqB,CAAC,IAAY;QAChC,MAAM,OAAO,GAAG,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;QAC7C,IAAI,CAAC,OAAO;YAAE,OAAO,IAAI,CAAC;QAC1B,qEAAqE;QACrE,oEAAoE;QACpE,+BAA+B;QAC/B,MAAM,eAAe,GAAG,OAAO,CAAC,OAAO,CAAC,qBAAqB,EAAE,EAAE,CAAC,CAAC;QACnE,OAAO,kBAAkB,CAAC,eAAe,CAAC,CAAC;IAC7C,CAAC;IAED,YAAY;QACV,OAAO,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC;IACzE,CAAC;IAED,YAAY,CACV,IAAY,EACZ,OAAe,EACf,IAAgE;QAEhE,MAAM,WAAW,GAAG,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC;QAClD,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;QACtC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YACxB,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACzC,CAAC;QAED,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,MAAM,CAAC;QAC3E,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC;YAC1C,CAAC,CAAC,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM;YACpC,CAAC,CAAC,CAAC,CAAC;QAEN,MAAM,iBAAiB,GAAG;YACxB,KAAK;YACL,WAAW,IAAI,CAAC,KAAK,GAAG;YACxB,UAAU,IAAI,GAAG;YACjB,cAAc,IAAI,CAAC,QAAQ,GAAG;YAC9B,aAAa,IAAI,CAAC,WAAW,GAAG;YAChC,UAAU,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG;YACpD,UAAU;YACV,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CACtB,cAAc,CAAC,CAAC,IAAI,mBAAmB,CAAC,CAAC,MAAM,iBAAiB,CAAC,CAAC,IAAI,GAAG,CAC1E;YACD,uBAAuB,IAAI,CAAC,gBAAgB,GAAG;SAChD,CAAC;QAEF,6EAA6E;QAC7E,sEAAsE;QACtE,mEAAmE;QACnE,MAAM,yBAAyB,GAAG,CAAC,GAAG,iBAAiB,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC;QACzF,MAAM,WAAW,GAAG,kBAAkB,CAAC,yBAAyB,CAAC,CAAC;QAElE,MAAM,WAAW,GAAG;YAClB,GAAG,iBAAiB;YACpB,kBAAkB,WAAW,GAAG;YAChC,KAAK;YACL,EAAE;SACH,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC;QAEvB,MAAM,OAAO,GAAG,WAAW,GAAG,QAAQ,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;QACnD,EAAE,CAAC,aAAa,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;QACvC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;QAEpC,MAAM,OAAO,GAAgB;YAC3B,IAAI;YACJ,GAAG,IAAI;YACP,WAAW;YACX,YAAY;SACb,CAAC;QACF,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;QAC/B,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,UAAU,CAAC,QAAgB,EAAE,OAAe,EAAE,aAAa,GAAG,EAAE;QAC9D,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;QACxD,MAAM,SAAS,GAAG,IAAI,IAAI,CACxB,IAAI,CAAC,GAAG,EAAE,GAAG,aAAa,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CACjD,CAAC,WAAW,EAAE,CAAC;QAEhB,MAAM,WAAW,GAAG;YAClB,KAAK;YACL,aAAa,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,GAAG;YACxC,gBAAgB,SAAS,GAAG;YAC5B,KAAK;YACL,EAAE;SACH,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAEb,EAAE,CAAC,aAAa,CAAC,UAAU,EAAE,WAAW,GAAG,OAAO,CAAC,CAAC;QACpD,OAAO,UAAU,CAAC;IACpB,CAAC;IAED,0BAA0B,CACxB,QAAgC,EAChC,YAAoC,EAAE;QAEtC,MAAM,UAAU,GAAG,EAAE,GAAG,QAAQ,EAAE,GAAG,SAAS,EAAE,CAAC;QACjD,OAAO,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE;YACpC,MAAM,OAAO,GAAG,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;YAC7C,MAAM,OAAO,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,OAAO,EAAE,CAAC;kBAC5D,CAAC,IAAI,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC;YAC1B,OAAO,OAAO,GAAG,OAAO,CAAC;QAC3B,CAAC,CAAC,CAAC;IACL,CAAC;IAED,sBAAsB,CAAC,SAAS,GAAG,GAAG;QACpC,OAAO,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,YAAY,GAAG,SAAS,CAAC,CAAC;IACrE,CAAC;IAED,qBAAqB;QACnB,MAAM,QAAQ,GAAa,EAAE,CAAC;QAC9B,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAEvB,IAAI,KAAe,CAAC;QACpB,IAAI,CAAC;YACH,KAAK,GAAG,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC;iBACpC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,SAAS,CAAC,CAAC;QACvD,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,QAAQ,CAAC;QAClB,CAAC;QAED,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;YAClD,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YACnD,MAAM,YAAY,GAAG,OAAO,CAAC,KAAK,CAAC,uBAAuB,CAAC,CAAC;YAC5D,IAAI,YAAY,EAAE,CAAC;gBACjB,MAAM,SAAS,GAAG,IAAI,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;gBACtD,IAAI,SAAS,GAAG,GAAG,EAAE,CAAC;oBACpB,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CACxB,IAAI,CAAC,UAAU,EACf,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CACrC,CAAC;oBACF,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;wBAC7B,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;oBAC9C,CAAC;oBACD,EAAE,CAAC,UAAU,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC;oBACnD,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACtB,CAAC;YACH,CAAC;QACH,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,iBAAiB;QACf,IAAI,CAAC,KAAK,CAAC,eAAe,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QACtD,IAAI,CAAC,UAAU,EAAE,CAAC;IACpB,CAAC;IAED,iBAAiB,CAAC,IAAY,EAAE,OAAe;QAC7C,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,EAAE,GAAG,IAAI,KAAK,CAAC,CAAC;QACnE,EAAE,CAAC,aAAa,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;IACvC,CAAC;IAED,gBAAgB,CAAC,IAAY;QAC3B,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,EAAE,GAAG,IAAI,KAAK,CAAC,CAAC;QACnE,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC;YAAE,OAAO,IAAI,CAAC;QAC3C,OAAO,EAAE,CAAC,YAAY,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;IAC7C,CAAC;IAED,kBAAkB,CAAC,IAAY;QAC7B,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,EAAE,GAAG,IAAI,KAAK,CAAC,CAAC;QACnE,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC;YAAE,OAAO,KAAK,CAAC;QAC5C,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;QACzB,OAAO,IAAI,CAAC;IACd,CAAC;IAEO,kBAAkB,CAAC,IAAY;QACrC,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,IAAI,KAAK,CAAC,CAAC;IAC/C,CAAC;IAEO,gBAAgB,CAAC,OAAoB;QAC3C,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;QAC7E,IAAI,QAAQ,IAAI,CAAC,EAAE,CAAC;YAClB,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,OAAO,CAAC;QAC1C,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACpC,CAAC;QACD,IAAI,CAAC,KAAK,CAAC,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC;QACtD,IAAI,CAAC,KAAK,CAAC,YAAY,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QACnD,IAAI,CAAC,UAAU,EAAE,CAAC;IACpB,CAAC;IAEO,gBAAgB;QACtB,OAAO;YACL,OAAO,EAAE,CAAC;YACV,YAAY,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACtC,eAAe,EAAE,IAAI;YACrB,QAAQ,EAAE,EAAE;YACZ,aAAa,EAAE,CAAC;SACjB,CAAC;IACJ,CAAC;IAEO,UAAU;QAChB,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;YACzD,MAAM,SAAS,GAAG,OAAO,CAAC,KAAK,CAAC,0BAA0B,CAAC,CAAC;YAC5D,IAAI,SAAS;gBAAE,OAAO,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;QACjD,CAAC;QAAC,MAAM,CAAC,CAAC,kBAAkB,CAAC,CAAC;QAC9B,OAAO,IAAI,CAAC,gBAAgB,EAAE,CAAC;IACjC,CAAC;IAEO,UAAU;QAChB,MAAM,eAAe,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAChD,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,CACpC,CAAC;QACF,MAAM,OAAO,GAAG;YACd,iCAAiC;YACjC,EAAE;YACF,kBAAkB,IAAI,CAAC,KAAK,CAAC,YAAY,EAAE;YAC3C,sBAAsB,IAAI,CAAC,KAAK,CAAC,eAAe,IAAI,OAAO,EAAE;YAC7D,mBAAmB,eAAe,CAAC,MAAM,EAAE;YAC3C,EAAE;YACF,aAAa;YACb,EAAE;YACF,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CACzB,SAAS,CAAC,CAAC,IAAI,UAAU,CAAC,CAAC,OAAO,MAAM,CAAC,CAAC,QAAQ,cAAc,CAAC,CAAC,WAAW,IAAI,CAClF;YACD,EAAE;YACF,2BAA2B;YAC3B,EAAE;YACF,SAAS;YACT,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;YACnC,KAAK;SACN,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAEb,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;IAC5C,CAAC;CACF"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cryptographic provenance utilities for the Fleet Knowledge Base.
|
|
3
|
+
*
|
|
4
|
+
* SPEC-fleet-knowledge-base-v1.2 §3.2.1:
|
|
5
|
+
* Every wiki article is anchored to its source material via SHA-256 hash chains.
|
|
6
|
+
* Sources are classified as raw (originating fleet signal) or derived (prior wiki).
|
|
7
|
+
*/
|
|
8
|
+
export interface SourceReference {
|
|
9
|
+
path: string;
|
|
10
|
+
sha256: string;
|
|
11
|
+
type: 'raw' | 'derived';
|
|
12
|
+
}
|
|
13
|
+
export declare function computeFileHash(filePath: string): string;
|
|
14
|
+
export declare function computeContentHash(content: string): string;
|
|
15
|
+
export declare function classifySource(sourcePath: string): 'raw' | 'derived';
|
|
16
|
+
//# sourceMappingURL=provenance.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provenance.d.ts","sourceRoot":"","sources":["../../src/knowledge/provenance.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,KAAK,GAAG,SAAS,CAAC;CACzB;AAED,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAGxD;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,KAAK,GAAG,SAAS,CAKpE"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cryptographic provenance utilities for the Fleet Knowledge Base.
|
|
3
|
+
*
|
|
4
|
+
* SPEC-fleet-knowledge-base-v1.2 §3.2.1:
|
|
5
|
+
* Every wiki article is anchored to its source material via SHA-256 hash chains.
|
|
6
|
+
* Sources are classified as raw (originating fleet signal) or derived (prior wiki).
|
|
7
|
+
*/
|
|
8
|
+
import * as crypto from 'node:crypto';
|
|
9
|
+
import * as fs from 'node:fs';
|
|
10
|
+
export function computeFileHash(filePath) {
|
|
11
|
+
const content = fs.readFileSync(filePath, 'utf-8');
|
|
12
|
+
return crypto.createHash('sha256').update(content).digest('hex');
|
|
13
|
+
}
|
|
14
|
+
export function computeContentHash(content) {
|
|
15
|
+
return crypto.createHash('sha256').update(content).digest('hex');
|
|
16
|
+
}
|
|
17
|
+
export function classifySource(sourcePath) {
|
|
18
|
+
if (sourcePath.startsWith('wiki/') || sourcePath.startsWith('intel/')) {
|
|
19
|
+
return 'derived';
|
|
20
|
+
}
|
|
21
|
+
return 'raw';
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=provenance.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provenance.js","sourceRoot":"","sources":["../../src/knowledge/provenance.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,MAAM,MAAM,aAAa,CAAC;AACtC,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAQ9B,MAAM,UAAU,eAAe,CAAC,QAAgB;IAC9C,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IACnD,OAAO,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AACnE,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,OAAe;IAChD,OAAO,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AACnE,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,UAAkB;IAC/C,IAAI,UAAU,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,UAAU,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QACtE,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared provenance verification utility (IH3).
|
|
3
|
+
*
|
|
4
|
+
* Used by both Grillo's assessment tool and Mighty Mark's wiki-integrity
|
|
5
|
+
* check to ensure identical verification logic.
|
|
6
|
+
*
|
|
7
|
+
* SPEC-fleet-knowledge-base-v1.2 §3.7
|
|
8
|
+
*/
|
|
9
|
+
import type { KnowledgeStore } from './knowledge-store.js';
|
|
10
|
+
export interface ProvenanceVerificationResult {
|
|
11
|
+
valid: boolean;
|
|
12
|
+
staleSources: string[];
|
|
13
|
+
missingSources: string[];
|
|
14
|
+
contentHashMatch: boolean;
|
|
15
|
+
}
|
|
16
|
+
export declare function verifyArticleProvenance(slug: string, store: KnowledgeStore): ProvenanceVerificationResult;
|
|
17
|
+
//# sourceMappingURL=verify-provenance.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verify-provenance.d.ts","sourceRoot":"","sources":["../../src/knowledge/verify-provenance.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,OAAO,KAAK,EAAE,cAAc,EAAe,MAAM,sBAAsB,CAAC;AAExE,MAAM,WAAW,4BAA4B;IAC3C,KAAK,EAAE,OAAO,CAAC;IACf,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,gBAAgB,EAAE,OAAO,CAAC;CAC3B;AAED,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,cAAc,GACpB,4BAA4B,CA8B9B"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared provenance verification utility (IH3).
|
|
3
|
+
*
|
|
4
|
+
* Used by both Grillo's assessment tool and Mighty Mark's wiki-integrity
|
|
5
|
+
* check to ensure identical verification logic.
|
|
6
|
+
*
|
|
7
|
+
* SPEC-fleet-knowledge-base-v1.2 §3.7
|
|
8
|
+
*/
|
|
9
|
+
import * as fs from 'node:fs';
|
|
10
|
+
import * as path from 'node:path';
|
|
11
|
+
import { computeFileHash } from './provenance.js';
|
|
12
|
+
export function verifyArticleProvenance(slug, store) {
|
|
13
|
+
const article = store.getArticle(slug);
|
|
14
|
+
if (!article) {
|
|
15
|
+
return { valid: false, staleSources: [], missingSources: [slug], contentHashMatch: false };
|
|
16
|
+
}
|
|
17
|
+
const storedHash = article.contentHash;
|
|
18
|
+
const actualHash = store.getArticleContentHash(slug);
|
|
19
|
+
const contentHashMatch = storedHash === actualHash;
|
|
20
|
+
const staleSources = [];
|
|
21
|
+
const missingSources = [];
|
|
22
|
+
for (const source of article.sources) {
|
|
23
|
+
const sourcePath = path.resolve(store.baseDir, source.path);
|
|
24
|
+
if (!fs.existsSync(sourcePath)) {
|
|
25
|
+
missingSources.push(source.path);
|
|
26
|
+
continue;
|
|
27
|
+
}
|
|
28
|
+
const currentHash = computeFileHash(sourcePath);
|
|
29
|
+
if (currentHash !== source.sha256) {
|
|
30
|
+
staleSources.push(source.path);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
const valid = contentHashMatch
|
|
34
|
+
&& staleSources.length === 0
|
|
35
|
+
&& missingSources.length === 0;
|
|
36
|
+
return { valid, staleSources, missingSources, contentHashMatch };
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=verify-provenance.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verify-provenance.js","sourceRoot":"","sources":["../../src/knowledge/verify-provenance.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,eAAe,EAAsB,MAAM,iBAAiB,CAAC;AAUtE,MAAM,UAAU,uBAAuB,CACrC,IAAY,EACZ,KAAqB;IAErB,MAAM,OAAO,GAAG,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;IACvC,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,EAAE,EAAE,cAAc,EAAE,CAAC,IAAI,CAAC,EAAE,gBAAgB,EAAE,KAAK,EAAE,CAAC;IAC7F,CAAC;IAED,MAAM,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC;IACvC,MAAM,UAAU,GAAG,KAAK,CAAC,qBAAqB,CAAC,IAAI,CAAC,CAAC;IACrD,MAAM,gBAAgB,GAAG,UAAU,KAAK,UAAU,CAAC;IAEnD,MAAM,YAAY,GAAa,EAAE,CAAC;IAClC,MAAM,cAAc,GAAa,EAAE,CAAC;IAEpC,KAAK,MAAM,MAAM,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;QACrC,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;QAC5D,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YAC/B,cAAc,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YACjC,SAAS;QACX,CAAC;QACD,MAAM,WAAW,GAAG,eAAe,CAAC,UAAU,CAAC,CAAC;QAChD,IAAI,WAAW,KAAK,MAAM,CAAC,MAAM,EAAE,CAAC;YAClC,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACjC,CAAC;IACH,CAAC;IAED,MAAM,KAAK,GAAG,gBAAgB;WACzB,YAAY,CAAC,MAAM,KAAK,CAAC;WACzB,cAAc,CAAC,MAAM,KAAK,CAAC,CAAC;IAEjC,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,gBAAgB,EAAE,CAAC;AACnE,CAAC"}
|
package/dist/plugin.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAoFH,MAAM,CAAC,OAAO,UAAU,QAAQ,CAAC,GAAG,EAAE,GAAG,QAwxBxC"}
|