mindlore 0.0.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/LICENSE +21 -0
- package/README.md +128 -0
- package/SCHEMA.md +221 -0
- package/hooks/lib/mindlore-common.cjs +90 -0
- package/hooks/mindlore-fts5-sync.cjs +91 -0
- package/hooks/mindlore-index.cjs +96 -0
- package/hooks/mindlore-post-compact.cjs +46 -0
- package/hooks/mindlore-pre-compact.cjs +48 -0
- package/hooks/mindlore-search.cjs +133 -0
- package/hooks/mindlore-session-end.cjs +68 -0
- package/hooks/mindlore-session-focus.cjs +42 -0
- package/package.json +55 -0
- package/plugin.json +47 -0
- package/scripts/init.cjs +335 -0
- package/scripts/lib/constants.cjs +49 -0
- package/scripts/mindlore-fts5-index.cjs +115 -0
- package/scripts/mindlore-fts5-search.cjs +122 -0
- package/scripts/mindlore-health-check.cjs +320 -0
- package/skills/mindlore-health/SKILL.md +55 -0
- package/skills/mindlore-ingest/SKILL.md +102 -0
- package/templates/INDEX.md +12 -0
- package/templates/log.md +4 -0
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* mindlore-health-check — 16-point structural health check for .mindlore/
|
|
6
|
+
*
|
|
7
|
+
* Usage: node scripts/mindlore-health-check.cjs [path-to-mindlore-dir]
|
|
8
|
+
*
|
|
9
|
+
* Exit codes: 0 = healthy, 1 = issues found
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
const fs = require('fs');
|
|
13
|
+
const path = require('path');
|
|
14
|
+
|
|
15
|
+
// ── Constants ──────────────────────────────────────────────────────────
|
|
16
|
+
|
|
17
|
+
const { DIRECTORIES, TYPE_TO_DIR } = require('./lib/constants.cjs');
|
|
18
|
+
|
|
19
|
+
// ── Helpers ────────────────────────────────────────────────────────────
|
|
20
|
+
|
|
21
|
+
function parseFrontmatter(content) {
|
|
22
|
+
const match = content.match(/^---\r?\n([\s\S]*?)\r?\n---/);
|
|
23
|
+
if (!match) return null;
|
|
24
|
+
|
|
25
|
+
const fm = {};
|
|
26
|
+
const lines = match[1].split('\n');
|
|
27
|
+
for (const line of lines) {
|
|
28
|
+
const colonIdx = line.indexOf(':');
|
|
29
|
+
if (colonIdx === -1) continue;
|
|
30
|
+
const key = line.slice(0, colonIdx).trim();
|
|
31
|
+
let value = line.slice(colonIdx + 1).trim();
|
|
32
|
+
// Handle arrays
|
|
33
|
+
if (value.startsWith('[') && value.endsWith(']')) {
|
|
34
|
+
value = value
|
|
35
|
+
.slice(1, -1)
|
|
36
|
+
.split(',')
|
|
37
|
+
.map((s) => s.trim());
|
|
38
|
+
}
|
|
39
|
+
fm[key] = value;
|
|
40
|
+
}
|
|
41
|
+
return fm;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Health check needs ALL .md files (no skip), so pass empty set
|
|
45
|
+
function getAllMdFiles(dir) {
|
|
46
|
+
return require('../hooks/lib/mindlore-common.cjs').getAllMdFiles(dir, new Set());
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// ── Checks ─────────────────────────────────────────────────────────────
|
|
50
|
+
|
|
51
|
+
class HealthChecker {
|
|
52
|
+
constructor(baseDir) {
|
|
53
|
+
this.baseDir = baseDir;
|
|
54
|
+
this.results = [];
|
|
55
|
+
this.passed = 0;
|
|
56
|
+
this.failed = 0;
|
|
57
|
+
this.warnings = 0;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
check(name, fn) {
|
|
61
|
+
try {
|
|
62
|
+
const result = fn();
|
|
63
|
+
if (result.ok) {
|
|
64
|
+
this.passed++;
|
|
65
|
+
this.results.push({ name, status: 'PASS', detail: result.detail });
|
|
66
|
+
} else if (result.warn) {
|
|
67
|
+
this.warnings++;
|
|
68
|
+
this.results.push({ name, status: 'WARN', detail: result.detail });
|
|
69
|
+
} else {
|
|
70
|
+
this.failed++;
|
|
71
|
+
this.results.push({ name, status: 'FAIL', detail: result.detail });
|
|
72
|
+
}
|
|
73
|
+
} catch (err) {
|
|
74
|
+
this.failed++;
|
|
75
|
+
this.results.push({ name, status: 'FAIL', detail: err.message });
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Check 1-9: Directory existence
|
|
80
|
+
checkDirectories() {
|
|
81
|
+
for (const dir of DIRECTORIES) {
|
|
82
|
+
this.check(`Directory: ${dir}/`, () => {
|
|
83
|
+
const dirPath = path.join(this.baseDir, dir);
|
|
84
|
+
if (fs.existsSync(dirPath)) {
|
|
85
|
+
return { ok: true, detail: 'exists' };
|
|
86
|
+
}
|
|
87
|
+
return { ok: false, detail: 'missing' };
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Check 10: SCHEMA.md parseable
|
|
93
|
+
checkSchema() {
|
|
94
|
+
this.check('SCHEMA.md', () => {
|
|
95
|
+
const schemaPath = path.join(this.baseDir, 'SCHEMA.md');
|
|
96
|
+
if (!fs.existsSync(schemaPath)) {
|
|
97
|
+
return { ok: false, detail: 'missing' };
|
|
98
|
+
}
|
|
99
|
+
const content = fs.readFileSync(schemaPath, 'utf8');
|
|
100
|
+
if (content.length < 100) {
|
|
101
|
+
return { ok: false, detail: 'too short (corrupted?)' };
|
|
102
|
+
}
|
|
103
|
+
if (!content.includes('## 1. Identity')) {
|
|
104
|
+
return { warn: true, detail: 'may be outdated (missing Identity section)' };
|
|
105
|
+
}
|
|
106
|
+
return { ok: true, detail: `${content.split('\n').length} lines` };
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Check 11: INDEX.md format
|
|
111
|
+
checkIndex() {
|
|
112
|
+
this.check('INDEX.md format', () => {
|
|
113
|
+
const indexPath = path.join(this.baseDir, 'INDEX.md');
|
|
114
|
+
if (!fs.existsSync(indexPath)) {
|
|
115
|
+
return { ok: false, detail: 'missing' };
|
|
116
|
+
}
|
|
117
|
+
const content = fs.readFileSync(indexPath, 'utf8');
|
|
118
|
+
const lines = content.trim().split('\n');
|
|
119
|
+
if (lines.length > 30) {
|
|
120
|
+
return {
|
|
121
|
+
warn: true,
|
|
122
|
+
detail: `${lines.length} lines (should be ~15-20, consider trimming)`,
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
return { ok: true, detail: `${lines.length} lines` };
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// Check 12: Database integrity
|
|
130
|
+
checkDatabase() {
|
|
131
|
+
this.check('mindlore.db FTS5', () => {
|
|
132
|
+
const dbPath = path.join(this.baseDir, 'mindlore.db');
|
|
133
|
+
if (!fs.existsSync(dbPath)) {
|
|
134
|
+
return { ok: false, detail: 'database missing' };
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
let Database;
|
|
138
|
+
try {
|
|
139
|
+
Database = require('better-sqlite3');
|
|
140
|
+
} catch (_err) {
|
|
141
|
+
return { warn: true, detail: 'better-sqlite3 not available, cannot verify' };
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
const db = new Database(dbPath, { readonly: true });
|
|
145
|
+
try {
|
|
146
|
+
const result = db.prepare('SELECT count(*) as cnt FROM mindlore_fts').get();
|
|
147
|
+
const hashResult = db
|
|
148
|
+
.prepare('SELECT count(*) as cnt FROM file_hashes')
|
|
149
|
+
.get();
|
|
150
|
+
return {
|
|
151
|
+
ok: true,
|
|
152
|
+
detail: `${result.cnt} indexed, ${hashResult.cnt} hashes`,
|
|
153
|
+
};
|
|
154
|
+
} catch (err) {
|
|
155
|
+
return { ok: false, detail: `FTS5 error: ${err.message}` };
|
|
156
|
+
} finally {
|
|
157
|
+
db.close();
|
|
158
|
+
}
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// Check 13: Orphan files (in .mindlore/ but not in FTS5)
|
|
163
|
+
checkOrphans() {
|
|
164
|
+
this.check('Orphan files', () => {
|
|
165
|
+
const dbPath = path.join(this.baseDir, 'mindlore.db');
|
|
166
|
+
if (!fs.existsSync(dbPath)) {
|
|
167
|
+
return { warn: true, detail: 'no database, cannot check' };
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
let Database;
|
|
171
|
+
try {
|
|
172
|
+
Database = require('better-sqlite3');
|
|
173
|
+
} catch (_err) {
|
|
174
|
+
return { warn: true, detail: 'better-sqlite3 not available' };
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
const mdFiles = getAllMdFiles(this.baseDir).filter(
|
|
178
|
+
(f) =>
|
|
179
|
+
!f.endsWith('INDEX.md') &&
|
|
180
|
+
!f.endsWith('SCHEMA.md') &&
|
|
181
|
+
!f.endsWith('log.md')
|
|
182
|
+
);
|
|
183
|
+
|
|
184
|
+
const db = new Database(dbPath, { readonly: true });
|
|
185
|
+
try {
|
|
186
|
+
const indexed = new Set();
|
|
187
|
+
const rows = db.prepare('SELECT path FROM file_hashes').all();
|
|
188
|
+
for (const row of rows) {
|
|
189
|
+
indexed.add(path.resolve(row.path));
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
const orphans = mdFiles.filter(
|
|
193
|
+
(f) => !indexed.has(path.resolve(f))
|
|
194
|
+
);
|
|
195
|
+
|
|
196
|
+
if (orphans.length === 0) {
|
|
197
|
+
return { ok: true, detail: 'no orphans' };
|
|
198
|
+
}
|
|
199
|
+
if (orphans.length <= 3) {
|
|
200
|
+
return {
|
|
201
|
+
warn: true,
|
|
202
|
+
detail: `${orphans.length} unindexed: ${orphans.map((f) => path.basename(f)).join(', ')}`,
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
return {
|
|
206
|
+
ok: false,
|
|
207
|
+
detail: `${orphans.length} unindexed files — run: npm run index`,
|
|
208
|
+
};
|
|
209
|
+
} finally {
|
|
210
|
+
db.close();
|
|
211
|
+
}
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
// Check 14-16: Frontmatter validation
|
|
216
|
+
checkFrontmatter() {
|
|
217
|
+
this.check('Frontmatter: slug + type', () => {
|
|
218
|
+
const mdFiles = getAllMdFiles(this.baseDir).filter(
|
|
219
|
+
(f) =>
|
|
220
|
+
!f.endsWith('INDEX.md') &&
|
|
221
|
+
!f.endsWith('SCHEMA.md') &&
|
|
222
|
+
!f.endsWith('log.md')
|
|
223
|
+
);
|
|
224
|
+
|
|
225
|
+
let missingSlug = 0;
|
|
226
|
+
let missingType = 0;
|
|
227
|
+
let wrongDir = 0;
|
|
228
|
+
|
|
229
|
+
for (const file of mdFiles) {
|
|
230
|
+
const content = fs.readFileSync(file, 'utf8').replace(/\r\n/g, '\n');
|
|
231
|
+
const fm = parseFrontmatter(content);
|
|
232
|
+
|
|
233
|
+
if (!fm) {
|
|
234
|
+
missingSlug++;
|
|
235
|
+
missingType++;
|
|
236
|
+
continue;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
if (!fm.slug) missingSlug++;
|
|
240
|
+
if (!fm.type) {
|
|
241
|
+
missingType++;
|
|
242
|
+
continue;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
// Check type-directory match
|
|
246
|
+
const expectedDir = TYPE_TO_DIR[fm.type];
|
|
247
|
+
if (expectedDir) {
|
|
248
|
+
const parentDir = path.basename(path.dirname(file));
|
|
249
|
+
if (parentDir !== expectedDir) {
|
|
250
|
+
wrongDir++;
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
const issues = [];
|
|
256
|
+
if (missingSlug > 0) issues.push(`${missingSlug} missing slug`);
|
|
257
|
+
if (missingType > 0) issues.push(`${missingType} missing type`);
|
|
258
|
+
if (wrongDir > 0) issues.push(`${wrongDir} type-dir mismatch`);
|
|
259
|
+
|
|
260
|
+
if (issues.length === 0) {
|
|
261
|
+
return {
|
|
262
|
+
ok: true,
|
|
263
|
+
detail: `${mdFiles.length} files validated`,
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
return {
|
|
267
|
+
ok: wrongDir > 0 ? false : undefined,
|
|
268
|
+
warn: wrongDir === 0,
|
|
269
|
+
detail: issues.join(', '),
|
|
270
|
+
};
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
// ── Run all ────────────────────────────────────────────────────────
|
|
275
|
+
|
|
276
|
+
run() {
|
|
277
|
+
this.checkDirectories();
|
|
278
|
+
this.checkSchema();
|
|
279
|
+
this.checkIndex();
|
|
280
|
+
this.checkDatabase();
|
|
281
|
+
this.checkOrphans();
|
|
282
|
+
this.checkFrontmatter();
|
|
283
|
+
return this;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
report() {
|
|
287
|
+
console.log('\n Mindlore Health Check\n');
|
|
288
|
+
|
|
289
|
+
for (const r of this.results) {
|
|
290
|
+
const icon =
|
|
291
|
+
r.status === 'PASS' ? '+' : r.status === 'WARN' ? '~' : '-';
|
|
292
|
+
console.log(` [${icon}] ${r.name}: ${r.detail}`);
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
const total = this.passed + this.failed + this.warnings;
|
|
296
|
+
console.log(
|
|
297
|
+
`\n Score: ${this.passed}/${total} passed, ${this.warnings} warnings, ${this.failed} failed\n`
|
|
298
|
+
);
|
|
299
|
+
|
|
300
|
+
return this.failed === 0;
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
// ── Main ───────────────────────────────────────────────────────────────
|
|
305
|
+
|
|
306
|
+
function main() {
|
|
307
|
+
const baseDir = process.argv[2] || path.join(process.cwd(), '.mindlore');
|
|
308
|
+
|
|
309
|
+
if (!fs.existsSync(baseDir)) {
|
|
310
|
+
console.error(` .mindlore/ not found at: ${baseDir}`);
|
|
311
|
+
console.error(' Run: npx mindlore init');
|
|
312
|
+
process.exit(1);
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
const checker = new HealthChecker(baseDir);
|
|
316
|
+
const healthy = checker.run().report();
|
|
317
|
+
process.exit(healthy ? 0 : 1);
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
main();
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: mindlore-health
|
|
3
|
+
description: Run 16-point structural health check on .mindlore/ knowledge base
|
|
4
|
+
effort: low
|
|
5
|
+
allowed-tools: [Bash, Read]
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# /mindlore-health
|
|
9
|
+
|
|
10
|
+
Run the 16-point structural health check on the `.mindlore/` knowledge base.
|
|
11
|
+
|
|
12
|
+
## Trigger
|
|
13
|
+
|
|
14
|
+
User says "health check", "mindlore health", "bilgi sistemi kontrol", "saglik kontrolu".
|
|
15
|
+
|
|
16
|
+
## Execution
|
|
17
|
+
|
|
18
|
+
1. Run the health check script:
|
|
19
|
+
```bash
|
|
20
|
+
node scripts/mindlore-health-check.cjs
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
2. Read the output and provide LLM interpretation:
|
|
24
|
+
- Explain any failures or warnings
|
|
25
|
+
- Suggest specific fixes for each issue
|
|
26
|
+
- Prioritize: FAIL > WARN > PASS
|
|
27
|
+
|
|
28
|
+
## 16 Checks
|
|
29
|
+
|
|
30
|
+
| # | Check | What It Validates |
|
|
31
|
+
|---|-------|-------------------|
|
|
32
|
+
| 1-9 | Directory existence | All 9 directories under .mindlore/ exist |
|
|
33
|
+
| 10 | SCHEMA.md | File exists and is parseable |
|
|
34
|
+
| 11 | INDEX.md format | File exists, ~15-20 lines (not bloated) |
|
|
35
|
+
| 12 | mindlore.db FTS5 | Database exists, FTS5 table queryable |
|
|
36
|
+
| 13 | Orphan files | All .md files are indexed in FTS5 |
|
|
37
|
+
| 14-16 | Frontmatter | slug + type present, type matches directory |
|
|
38
|
+
|
|
39
|
+
## Common Fixes
|
|
40
|
+
|
|
41
|
+
| Issue | Fix |
|
|
42
|
+
|-------|-----|
|
|
43
|
+
| Missing directory | `npx mindlore init` (idempotent) |
|
|
44
|
+
| Database missing | `npx mindlore init` |
|
|
45
|
+
| Orphan files | `npm run index` (full re-index) |
|
|
46
|
+
| INDEX.md too long | Trim to ~15-20 lines, move details to domains/ |
|
|
47
|
+
| Type-dir mismatch | Move file to correct directory or fix frontmatter type |
|
|
48
|
+
| Missing frontmatter | Add YAML frontmatter with slug and type |
|
|
49
|
+
|
|
50
|
+
## Output Format
|
|
51
|
+
|
|
52
|
+
Report results clearly:
|
|
53
|
+
- Total score: X/16 passed
|
|
54
|
+
- List any FAIL or WARN items with specific fix commands
|
|
55
|
+
- If all pass: "Knowledge base is healthy"
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: mindlore-ingest
|
|
3
|
+
description: Add new knowledge sources to .mindlore/ (URL, text, file, PDF, GitHub repo)
|
|
4
|
+
effort: medium
|
|
5
|
+
allowed-tools: [Read, Write, Edit, Bash, Grep, Glob, Agent, WebFetch]
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# /mindlore-ingest
|
|
9
|
+
|
|
10
|
+
Add a new knowledge source to the `.mindlore/` knowledge base.
|
|
11
|
+
|
|
12
|
+
## Trigger
|
|
13
|
+
|
|
14
|
+
User shares a URL, text, file, or says "kaynak ekle", "source ingest", "bu linki kaydet", "knowledge ingest".
|
|
15
|
+
|
|
16
|
+
## Modes
|
|
17
|
+
|
|
18
|
+
### URL Mode
|
|
19
|
+
1. Extract content from URL:
|
|
20
|
+
- If `markitdown` is available: `markitdown <url>` (best quality, zero tokens)
|
|
21
|
+
- Else: use `WebFetch` or `ctx_fetch_and_index`
|
|
22
|
+
2. Save raw capture to `.mindlore/raw/` with frontmatter:
|
|
23
|
+
```yaml
|
|
24
|
+
---
|
|
25
|
+
slug: source-name-kebab
|
|
26
|
+
type: raw
|
|
27
|
+
source_url: https://...
|
|
28
|
+
date_captured: YYYY-MM-DD
|
|
29
|
+
tags: [tag1, tag2]
|
|
30
|
+
---
|
|
31
|
+
```
|
|
32
|
+
3. Summarize into `.mindlore/sources/` with full frontmatter:
|
|
33
|
+
```yaml
|
|
34
|
+
---
|
|
35
|
+
slug: source-name-kebab
|
|
36
|
+
type: source
|
|
37
|
+
title: Human Readable Title
|
|
38
|
+
source_url: https://...
|
|
39
|
+
source_type: github-repo|blog|docs|video|x-thread
|
|
40
|
+
date_captured: YYYY-MM-DD
|
|
41
|
+
tags: [tag1, tag2]
|
|
42
|
+
quality: high|medium|low
|
|
43
|
+
ingested: true
|
|
44
|
+
---
|
|
45
|
+
```
|
|
46
|
+
4. Update relevant domain page(s) in `.mindlore/domains/` (max 2)
|
|
47
|
+
5. Update `.mindlore/INDEX.md` stats line
|
|
48
|
+
6. Append entry to `.mindlore/log.md`
|
|
49
|
+
7. Run FTS5 re-index: `npm run index`
|
|
50
|
+
|
|
51
|
+
### Text Mode
|
|
52
|
+
1. User pastes text directly
|
|
53
|
+
2. Save to `.mindlore/raw/` with `source_type: text-paste`
|
|
54
|
+
3. Follow steps 3-7 from URL mode
|
|
55
|
+
|
|
56
|
+
### PDF Mode
|
|
57
|
+
1. Read PDF with CC Read tool: `Read(file_path, pages: "1-5")` (max 20 pages/request)
|
|
58
|
+
2. **Do NOT use markitdown for PDF** — quality is poor
|
|
59
|
+
3. Save extracted text to `.mindlore/raw/`
|
|
60
|
+
4. Follow steps 3-7 from URL mode
|
|
61
|
+
5. For v0.3+: Marker CLI or Chandra as optional alternatives
|
|
62
|
+
|
|
63
|
+
### File Mode
|
|
64
|
+
1. Read the file with `Read` tool
|
|
65
|
+
2. Save to `.mindlore/raw/`
|
|
66
|
+
3. Follow steps 3-7 from URL mode
|
|
67
|
+
|
|
68
|
+
## Source Summary Format
|
|
69
|
+
|
|
70
|
+
The sources/ file should contain:
|
|
71
|
+
- **1-paragraph summary** of what the source is about
|
|
72
|
+
- **Key takeaways** (3-7 bullet points)
|
|
73
|
+
- **Relevance to project** (why this matters)
|
|
74
|
+
- **Related** links to other sources/domains in .mindlore/
|
|
75
|
+
|
|
76
|
+
## Quality Assessment
|
|
77
|
+
|
|
78
|
+
- `high`: Primary source, authoritative, detailed, directly relevant
|
|
79
|
+
- `medium`: Useful but secondary, partial coverage, or tangentially relevant
|
|
80
|
+
- `low`: Reference only, outdated, or low signal-to-noise
|
|
81
|
+
|
|
82
|
+
## Domain Update Rules
|
|
83
|
+
|
|
84
|
+
- Read the relevant domain page first
|
|
85
|
+
- Add new information under the appropriate section
|
|
86
|
+
- Add backlink to the source in the domain's references
|
|
87
|
+
- Update max 2 domain pages per ingest (prevent scope creep)
|
|
88
|
+
- If no relevant domain exists, note it — don't create one during ingest
|
|
89
|
+
|
|
90
|
+
## INDEX.md Update
|
|
91
|
+
|
|
92
|
+
Only update the stats line: increment source count and total count.
|
|
93
|
+
```
|
|
94
|
+
N source, N analysis, N total
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## Post-Ingest Verification
|
|
98
|
+
|
|
99
|
+
After ingest, run health check:
|
|
100
|
+
```bash
|
|
101
|
+
node scripts/mindlore-health-check.cjs
|
|
102
|
+
```
|
package/templates/log.md
ADDED