solopup-memory 0.21.0-beta.2 → 0.22.0-beta.3
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/CHANGELOG.md +37 -0
- package/COMPATIBILITY.md +8 -5
- package/DETECTION.md +139 -0
- package/DREAMING-DESIGN.md +167 -0
- package/README.en.md +35 -6
- package/README.md +44 -7
- package/RELEASE.md +36 -0
- package/SECURITY.md +11 -0
- package/context-history.mjs +20 -3
- package/detect.mjs +441 -0
- package/eval/bench-detect.mjs +107 -0
- package/eval/semantic/cases.json +387 -0
- package/eval/semantic-suite.mjs +156 -0
- package/index.mjs +117 -27
- package/managed-policy.mjs +3 -1
- package/package.json +91 -68
- package/privacy.mjs +25 -0
- package/scripts/demo-source-recall.mjs +123 -0
- package/scripts/detect.mjs +69 -0
- package/scripts/dream.mjs +205 -0
- package/scripts/probe-history.mjs +92 -0
- package/scripts/probe-load.mjs +1 -1
- package/scripts/probe-package.mjs +6 -2
- package/scripts/security-check.mjs +173 -0
- package/scripts/soak.mjs +219 -0
- package/scripts/telemetry.mjs +187 -0
- package/scripts/verify.mjs +3 -1
- package/{test-adversarial.mjs → test/test-adversarial.mjs} +5 -5
- package/{test-belief-revision.mjs → test/test-belief-revision.mjs} +7 -7
- package/{test-candidates.mjs → test/test-candidates.mjs} +4 -4
- package/{test-capture-diagnostics.mjs → test/test-capture-diagnostics.mjs} +6 -6
- package/{test-capture-field-lineage.mjs → test/test-capture-field-lineage.mjs} +4 -4
- package/{test-capture-inputs.mjs → test/test-capture-inputs.mjs} +8 -8
- package/{test-capture-jobs.mjs → test/test-capture-jobs.mjs} +5 -5
- package/{test-capture-projections.mjs → test/test-capture-projections.mjs} +12 -12
- package/{test-capture-revision.mjs → test/test-capture-revision.mjs} +6 -6
- package/{test-capture-submission.mjs → test/test-capture-submission.mjs} +3 -3
- package/{test-capture-validation-flow.mjs → test/test-capture-validation-flow.mjs} +5 -5
- package/{test-capture-validation-job.mjs → test/test-capture-validation-job.mjs} +5 -5
- package/{test-capture-validation-lineage.mjs → test/test-capture-validation-lineage.mjs} +2 -2
- package/{test-capture-validation.mjs → test/test-capture-validation.mjs} +2 -2
- package/{test-capture.mjs → test/test-capture.mjs} +20 -20
- package/{test-compaction-compat.mjs → test/test-compaction-compat.mjs} +5 -5
- package/{test-compat.mjs → test/test-compat.mjs} +3 -3
- package/{test-concurrency.mjs → test/test-concurrency.mjs} +3 -3
- package/{test-conflict.mjs → test/test-conflict.mjs} +2 -2
- package/{test-context-history.mjs → test/test-context-history.mjs} +1 -1
- package/{test-control-schema.mjs → test/test-control-schema.mjs} +1 -1
- package/test/test-detect.mjs +125 -0
- package/test/test-dream-plan.mjs +72 -0
- package/test/test-dsh-registration.mjs +111 -0
- package/{test-episodes.mjs → test/test-episodes.mjs} +5 -5
- package/{test-explicit-memory.mjs → test/test-explicit-memory.mjs} +4 -4
- package/{test-field-lineage.mjs → test/test-field-lineage.mjs} +4 -4
- package/{test-history.mjs → test/test-history.mjs} +4 -4
- package/{test-inline-summary.mjs → test/test-inline-summary.mjs} +5 -5
- package/{test-legacy-source-identity.mjs → test/test-legacy-source-identity.mjs} +2 -2
- package/{test-links.mjs → test/test-links.mjs} +4 -4
- package/{test-managed-access.mjs → test/test-managed-access.mjs} +29 -5
- package/{test-managed-activation.mjs → test/test-managed-activation.mjs} +5 -5
- package/{test-meaning.mjs → test/test-meaning.mjs} +6 -6
- package/{test-native-service-lifecycle.mjs → test/test-native-service-lifecycle.mjs} +1 -1
- package/{test-native-write-validation.mjs → test/test-native-write-validation.mjs} +10 -4
- package/{test-packaging.mjs → test/test-packaging.mjs} +32 -5
- package/{test-paired-analysis.mjs → test/test-paired-analysis.mjs} +1 -1
- package/{test-patch.mjs → test/test-patch.mjs} +11 -11
- package/{test-plugin-contract.mjs → test/test-plugin-contract.mjs} +4 -4
- package/test/test-privacy.mjs +65 -0
- package/{test-project-stores.mjs → test/test-project-stores.mjs} +5 -5
- package/{test-publication.mjs → test/test-publication.mjs} +4 -4
- package/{test-restore.mjs → test/test-restore.mjs} +11 -11
- package/{test-retrieval.mjs → test/test-retrieval.mjs} +2 -2
- package/{test-revision-admission.mjs → test/test-revision-admission.mjs} +3 -3
- package/{test-rule-admission.mjs → test/test-rule-admission.mjs} +8 -8
- package/{test-runtime-startup.mjs → test/test-runtime-startup.mjs} +2 -2
- package/{test-schema.mjs → test/test-schema.mjs} +2 -2
- package/{test-security.mjs → test/test-security.mjs} +6 -6
- package/test/test-semantic-suite.mjs +20 -0
- package/{test-service-readiness.mjs → test/test-service-readiness.mjs} +1 -1
- package/{test-smell.mjs → test/test-smell.mjs} +4 -4
- package/{test-snapshots.mjs → test/test-snapshots.mjs} +3 -3
- package/{test-source-completeness.mjs → test/test-source-completeness.mjs} +6 -6
- package/{test-source-key.mjs → test/test-source-key.mjs} +2 -2
- package/{test-source-retirement.mjs → test/test-source-retirement.mjs} +4 -4
- package/{test-status-both.mjs → test/test-status-both.mjs} +12 -4
- package/{test-supersede.mjs → test/test-supersede.mjs} +3 -3
- package/test/test-telemetry.mjs +60 -0
- package/{test-text-admission.mjs → test/test-text-admission.mjs} +6 -6
- package/{test-tool-inputs.mjs → test/test-tool-inputs.mjs} +1 -1
- package/{test-tool-observations.mjs → test/test-tool-observations.mjs} +6 -6
- package/{test-tool-write-guard.mjs → test/test-tool-write-guard.mjs} +3 -3
- package/{test-tool-write-lifecycle.mjs → test/test-tool-write-lifecycle.mjs} +3 -3
- package/{test-usability.mjs → test/test-usability.mjs} +7 -7
- package/{test-validation-source-refs.mjs → test/test-validation-source-refs.mjs} +2 -2
- package/{test-validation-transition-context.mjs → test/test-validation-transition-context.mjs} +1 -1
- package/{test-withdrawal-archives.mjs → test/test-withdrawal-archives.mjs} +6 -6
- package/{test-withdrawal.mjs → test/test-withdrawal.mjs} +2 -2
- package/{test.mjs → test/test.mjs} +4 -4
- package/version.mjs +1 -1
package/index.mjs
CHANGED
|
@@ -5,6 +5,7 @@ export {initializeManagedMemory,managedMemoryStatus} from './managed-access.mjs'
|
|
|
5
5
|
import {createObservationTracker,observationRoots,OBSERVATION_REFERENCE_SCHEMA,OBSERVATION_LIST_SCHEMA} from './tool-observations.mjs'
|
|
6
6
|
import {createToolInputTracker} from './tool-inputs.mjs'
|
|
7
7
|
import {memoryProtocol} from './memory-protocol.mjs'
|
|
8
|
+
import {privateMemory,publicMemoryRecords,publicMemoryIndex,PRIVATE_MEMORY_NOTICE} from './privacy.mjs'
|
|
8
9
|
import {nativeOwnerEvidence,validateNativeWrite} from './native-write-validation.mjs'
|
|
9
10
|
import {toolProposal} from './source-record.mjs'
|
|
10
11
|
import {revisionMode,prepareValueRevision,inheritedRoots} from './field-lineage.mjs'
|
|
@@ -291,8 +292,9 @@ function renderScopeLocal(scope, dir) {
|
|
|
291
292
|
let flagged = 0
|
|
292
293
|
const kept = []
|
|
293
294
|
const policy = withdrawalPolicy(dir)
|
|
294
|
-
const typed=activeMeanings(candidateSnapshot(dir,scope).records),assessmentRecords=effectiveSourceRecords(dir,scope)
|
|
295
|
+
const typed=activeMeanings(candidateSnapshot(dir,scope).records),assessmentRecords=publicMemoryRecords(effectiveSourceRecords(dir,scope))
|
|
295
296
|
for (const line of filterWithdrawn(index.text, policy, true).split('\n')) {
|
|
297
|
+
if (privateMemory(meaningForLine(typed,line),line)) continue
|
|
296
298
|
if (line.trim().startsWith('- [')) {
|
|
297
299
|
if (isExpired(line, now)) {
|
|
298
300
|
hidden += 1
|
|
@@ -888,7 +890,7 @@ function writeMemoryLocal({ type, dir, line, detail, summary, expires, supersede
|
|
|
888
890
|
}
|
|
889
891
|
|
|
890
892
|
// 相似度闸:改写同一件事却再叠一条,会让新旧两条同时被注入、给出矛盾信息。
|
|
891
|
-
// 0.
|
|
893
|
+
// 0.9 以上直接拒绝并指出候选;0.8–0.9 放行但带警告(避免误伤「相似但不同」的条目)。
|
|
892
894
|
let similarWarning
|
|
893
895
|
// 完全重复走 duplicate 分支(幂等返回),相似度闸只管「像但不是同一句」
|
|
894
896
|
const alias = hasTopicDetail(cleanDetail) ? undefined : routeAlias(cleanLine, type)
|
|
@@ -1048,16 +1050,19 @@ function writeMemoryLocal({ type, dir, line, detail, summary, expires, supersede
|
|
|
1048
1050
|
evidence: provenance?.evidence,
|
|
1049
1051
|
basis: provenance?.basis,
|
|
1050
1052
|
})
|
|
1053
|
+
const privateLines=new Set(liveSourceRecords(dir,scope).filter(privateMemory).map(record=>record.indexLine).filter(Boolean))
|
|
1054
|
+
const hiddenLine=line=>privateLines.has(line)||privateMemory(line)
|
|
1055
|
+
const visibleWarnings=warnings.filter(w=>!privateMemory(w)&&![...privateLines].some(line=>w.includes(summaryOf(line))))
|
|
1051
1056
|
return {
|
|
1052
1057
|
path: indexFile,
|
|
1053
1058
|
indexLine: cleanLine,
|
|
1054
1059
|
duplicate: false,
|
|
1055
1060
|
lineCount: next.split(/\r?\n/).length,
|
|
1056
1061
|
...(detailPath === undefined ? {} : { detailPath }),
|
|
1057
|
-
...(supersededLine === undefined ? {} : { superseded: supersededLine }),
|
|
1062
|
+
...(supersededLine === undefined||hiddenLine(supersededLine) ? {} : { superseded: supersededLine }),
|
|
1058
1063
|
id: newId,
|
|
1059
|
-
related,
|
|
1060
|
-
...(
|
|
1064
|
+
related:related.filter(edge=>!hiddenLine(edge.line)),
|
|
1065
|
+
...(visibleWarnings.length === 0 ? {} : { warning: visibleWarnings.join(';') }),
|
|
1061
1066
|
}
|
|
1062
1067
|
}
|
|
1063
1068
|
return lockToken === REVIEW_LOCK ? execute() : withLock(dir, execute)
|
|
@@ -1219,8 +1224,32 @@ function statusOfLocal(dir) {
|
|
|
1219
1224
|
}
|
|
1220
1225
|
|
|
1221
1226
|
/**
|
|
1222
|
-
*
|
|
1223
|
-
*
|
|
1227
|
+
* L0 检测摘要:把 detect.mjs 的 findings 压成计数,避免状态输出膨胀。
|
|
1228
|
+
* 动态导入是为了不形成 index ↔ detect 的静态循环(detect 依赖本文件的纯函数)。
|
|
1229
|
+
*/
|
|
1230
|
+
async function lintStatus(dir, scope) {
|
|
1231
|
+
try {
|
|
1232
|
+
const { detectStore } = await import('./detect.mjs')
|
|
1233
|
+
const report = detectStore(dir, { scope })
|
|
1234
|
+
const counts = new Map()
|
|
1235
|
+
for (const finding of report.findings) {
|
|
1236
|
+
if (finding.severity === 'info') continue
|
|
1237
|
+
const row = counts.get(finding.id) ?? { id: finding.id, severity: finding.severity, count: 0 }
|
|
1238
|
+
row.count += 1
|
|
1239
|
+
counts.set(finding.id, row)
|
|
1240
|
+
}
|
|
1241
|
+
return {
|
|
1242
|
+
errors: report.summary.errors,
|
|
1243
|
+
warnings: report.summary.warnings,
|
|
1244
|
+
checks: [...counts.values()].sort((left, right) => (left.id < right.id ? -1 : left.id > right.id ? 1 : 0)),
|
|
1245
|
+
}
|
|
1246
|
+
} catch {
|
|
1247
|
+
// 检测器本身坏了不能伪装成“库没问题”。
|
|
1248
|
+
return { errors: 0, warnings: 1, checks: [{ id: 'lint-unavailable', severity: 'warning', count: 1 }] }
|
|
1249
|
+
}
|
|
1250
|
+
}
|
|
1251
|
+
|
|
1252
|
+
/**
|
|
1224
1253
|
* 存在的原因:索引超上限时,被省略的条目对模型完全不可见(`lookupLinks` 只查索引)。
|
|
1225
1254
|
* 检索是确定性的:归一化后做子串匹配,不做正则、不做模糊。
|
|
1226
1255
|
*
|
|
@@ -1245,7 +1274,7 @@ function effectiveSourceRecords(dir,scope,indexText,includeUntyped=false){
|
|
|
1245
1274
|
}
|
|
1246
1275
|
|
|
1247
1276
|
/** Current index-only legacy entries are visible as unclassified data, never inherited sources. */
|
|
1248
|
-
function validationCurrentRecords(dir,scope,records){
|
|
1277
|
+
function validationCurrentRecords(dir,scope,records,privateTarget){
|
|
1249
1278
|
const policy=withdrawalPolicy(dir),index=filterWithdrawn(readTextSafe(join(dir,'MEMORY.md'))??'',policy,true)
|
|
1250
1279
|
const known=new Set(records.map(r=>r.indexLine??indexLine(r.type,r.summary,r.expires,r.detail!==undefined))),rows=[...records]
|
|
1251
1280
|
for(const line of new Set(index.split(/\r?\n/).map(line=>line.trim()))){
|
|
@@ -1253,7 +1282,7 @@ function validationCurrentRecords(dir,scope,records){
|
|
|
1253
1282
|
const type=/^- \[(user|feedback|project|reference)\] /.exec(line)?.[1];if(!type)continue
|
|
1254
1283
|
rows.push({id:createHash('sha256').update('memory-unclassified-current-index:'+scope+':'+line).digest('hex'),status:'recorded',scope,type,summary:summaryOf(line),indexLine:line,legacyIndexOnly:true,expires:/ \(exp:(\d{4}-\d{2}-\d{2})\)$/.exec(line)?.[1]})
|
|
1255
1284
|
}
|
|
1256
|
-
return rows
|
|
1285
|
+
return rows.filter(row=>!privateMemory(row)||typeof privateTarget==='string'&&privateTarget.length>0&&row.indexLine?.includes(privateTarget))
|
|
1257
1286
|
}
|
|
1258
1287
|
|
|
1259
1288
|
function publishIndexChange(dir,before,after,reason){
|
|
@@ -1269,6 +1298,7 @@ function searchHistoricalStores(stores,needle,options,context,task,limit,mode){
|
|
|
1269
1298
|
const policy=withdrawalPolicy(dir),index=filterWithdrawn(readTextSafe(join(dir,'MEMORY.md'))??'',policy,true)
|
|
1270
1299
|
const result=historyRows(dir,{scope,index,revoked:policy.revoked,atSequence:options.atSequence,asOf:options.asOf,expiredAt:isExpired});coverage.push(result.coverage)
|
|
1271
1300
|
for(const {row,line,history}of result.rows){
|
|
1301
|
+
if(options.includePrivate!==true&&privateMemory(row.source,row.line))continue
|
|
1272
1302
|
const interpretation=row.source.meaning?meaningView(row.source,context,task):undefined
|
|
1273
1303
|
if(interpretation?.applicability==='not-applicable')continue
|
|
1274
1304
|
if(interpretation)interpretation.advice={action:'continue',reason:'historical-record-is-not-a-current-instruction',authority:'none'}
|
|
@@ -1298,6 +1328,7 @@ function searchScopedStoresLocal(stores, query, options = {}) {
|
|
|
1298
1328
|
if (needle.length > 200) throw new Error('memory_search: query 太长(上限 200 字)')
|
|
1299
1329
|
const limit = Math.max(1, Math.min(20, options.limit ?? 8))
|
|
1300
1330
|
const mode = options.mode ?? 'ranked'
|
|
1331
|
+
if(options.includePrivate!==undefined&&typeof options.includePrivate!=='boolean')throw Error('memory-search-invalid-private-option')
|
|
1301
1332
|
if (mode !== 'exact' && mode !== 'ranked') throw new Error('memory_search: mode 必须是 exact 或 ranked')
|
|
1302
1333
|
const context=normalizeContext(options.context),task=normalizeTask(options.task)
|
|
1303
1334
|
if(options.view!==undefined&&!['current','history'].includes(options.view))throw new Error('memory-search-invalid-view')
|
|
@@ -1306,7 +1337,7 @@ function searchScopedStoresLocal(stores, query, options = {}) {
|
|
|
1306
1337
|
|
|
1307
1338
|
const files = stores.flatMap(({ dir, scope }) => {
|
|
1308
1339
|
const policy = withdrawalPolicy(dir)
|
|
1309
|
-
const owned=liveSourceRecords(dir,scope).filter(record=>['recorded','adopted'].includes(record.status)),typed=activeMeanings(owned),assessmentRecords=effectiveSourceRecords(dir,scope)
|
|
1340
|
+
const owned=liveSourceRecords(dir,scope).filter(record=>['recorded','adopted'].includes(record.status)),typed=activeMeanings(owned),assessmentRecords=options.includePrivate===true?effectiveSourceRecords(dir,scope):publicMemoryRecords(effectiveSourceRecords(dir,scope))
|
|
1310
1341
|
return ['MEMORY.md', ...TYPES.map(type => `${type}.md`)].map(name => ({
|
|
1311
1342
|
name, path: join(dir, name), policy, scope, typed, owned, assessmentRecords, key: scope === undefined ? name : `${scope}/${name}`,
|
|
1312
1343
|
}))
|
|
@@ -1319,12 +1350,16 @@ function searchScopedStoresLocal(stores, query, options = {}) {
|
|
|
1319
1350
|
for (const file of files) {
|
|
1320
1351
|
const text = readTextSafe(file.path)
|
|
1321
1352
|
if (text === undefined) continue
|
|
1353
|
+
// Legacy topic paragraphs may span lines without record markers. Never
|
|
1354
|
+
// return the unlabelled continuation of a recognized private paragraph.
|
|
1355
|
+
if(file.name!=='MEMORY.md'&&options.includePrivate!==true&&privateMemory(text))continue
|
|
1322
1356
|
let lineNumber = 0
|
|
1323
1357
|
const filtered=filterWithdrawn(text,file.policy,file.name==='MEMORY.md'),details=file.name==='MEMORY.md'?undefined:detailedMeanings(file.owned,filtered)
|
|
1324
1358
|
for (const raw of filtered.split('\n')) {
|
|
1325
1359
|
lineNumber += 1
|
|
1326
1360
|
if(file.name==='MEMORY.md'&&isExpired(raw))continue
|
|
1327
1361
|
const record=file.name==='MEMORY.md'?meaningForLine(file.typed,raw):details.get(lineNumber)
|
|
1362
|
+
if(options.includePrivate!==true&&privateMemory(record,raw))continue
|
|
1328
1363
|
if(record?.expires&&isExpired(`placeholder (exp:${record.expires})`))continue
|
|
1329
1364
|
const interpretation=record?.meaning?meaningView(record,context,task,file.assessmentRecords):undefined
|
|
1330
1365
|
if(interpretation?.applicability==='not-applicable')continue
|
|
@@ -1599,6 +1634,8 @@ function readLog(dir) {
|
|
|
1599
1634
|
* @param query - `{ id }` 或 `{ match }`(索引行子串,必须唯一)。
|
|
1600
1635
|
*/
|
|
1601
1636
|
function lookupLinksLocal(dir, query) {
|
|
1637
|
+
const hiddenLines=new Set(liveSourceRecords(dir).filter(privateMemory).map(record=>record.indexLine).filter(Boolean))
|
|
1638
|
+
const hidden=line=>hiddenLines.has(line)||privateMemory(line)
|
|
1602
1639
|
assertPublicationClear(dir)
|
|
1603
1640
|
const policy = withdrawalPolicy(dir)
|
|
1604
1641
|
const events = readLog(dir).filter((e) => !policy.memoryIds.includes(e.id) && !policy.lineHashes.includes(normalizedLineHash(String(e.line ?? ''))))
|
|
@@ -1607,7 +1644,7 @@ function lookupLinksLocal(dir, query) {
|
|
|
1607
1644
|
const live = new Map()
|
|
1608
1645
|
for (const line of current.split('\n')) {
|
|
1609
1646
|
const trimmed = line.trim()
|
|
1610
|
-
if (trimmed.startsWith('- [')) live.set(entryId(trimmed), trimmed)
|
|
1647
|
+
if (trimmed.startsWith('- [')&&!hidden(trimmed)) live.set(entryId(trimmed), trimmed)
|
|
1611
1648
|
}
|
|
1612
1649
|
|
|
1613
1650
|
let key = query.id
|
|
@@ -1628,8 +1665,9 @@ function lookupLinksLocal(dir, query) {
|
|
|
1628
1665
|
const inserted = events.filter((event) => event.op === 'insert' && event.id === key)
|
|
1629
1666
|
const line = live.get(key) ?? inserted.at(-1)?.line ?? events.find((event) => event.id === key)?.line
|
|
1630
1667
|
if (line === undefined) return { found: false, related: [], backlinks: [] }
|
|
1668
|
+
if(hidden(line))return{found:false,related:[],backlinks:[]}
|
|
1631
1669
|
|
|
1632
|
-
const related = inserted.at(-1)?.related ?? []
|
|
1670
|
+
const related = (inserted.at(-1)?.related ?? []).filter(item=>!hidden(item.line))
|
|
1633
1671
|
|
|
1634
1672
|
// 入边要顺着取代链找:指向被取代旧条目的边,等同指向新条目。
|
|
1635
1673
|
// 否则「改了一条记忆」就等于把它从图上拔掉。
|
|
@@ -1640,6 +1678,7 @@ function lookupLinksLocal(dir, query) {
|
|
|
1640
1678
|
const backlinks = []
|
|
1641
1679
|
for (const event of events) {
|
|
1642
1680
|
if (event.op !== 'insert' || lineage.has(event.id)) continue
|
|
1681
|
+
if(hidden(event.line))continue
|
|
1643
1682
|
if (!(event.related ?? []).some((item) => lineage.has(item.id))) continue
|
|
1644
1683
|
if (backlinks.some((item) => item.id === event.id)) continue
|
|
1645
1684
|
backlinks.push({ id: event.id, line: event.line })
|
|
@@ -1661,7 +1700,7 @@ function lookupLinksLocal(dir, query) {
|
|
|
1661
1700
|
backlinks: backlinks.slice(0, RELATION_LIMIT),
|
|
1662
1701
|
backlinksTotal: backlinks.length,
|
|
1663
1702
|
...(replaced?.supersededById === undefined ? {} : { supersededById: replaced.supersededById }),
|
|
1664
|
-
...(supersedesLine === undefined ? {} : { supersedesLine }),
|
|
1703
|
+
...(supersedesLine === undefined||hidden(supersedesLine) ? {} : { supersedesLine }),
|
|
1665
1704
|
}
|
|
1666
1705
|
}
|
|
1667
1706
|
|
|
@@ -1777,7 +1816,7 @@ async function admitNativeWrite(ctx,sourceInputs,config,args,exec,target){
|
|
|
1777
1816
|
const revision=readOwned(()=>{
|
|
1778
1817
|
const value=storeRevision(target.dir)
|
|
1779
1818
|
const sourceRecords=effectiveSourceRecords(target.dir,target.scope,undefined,true)
|
|
1780
|
-
currentRecords=validationCurrentRecords(target.dir,target.scope,sourceRecords)
|
|
1819
|
+
currentRecords=validationCurrentRecords(target.dir,target.scope,sourceRecords,target.supersedes)
|
|
1781
1820
|
if(target.supersedes!==undefined){
|
|
1782
1821
|
const hits=(readTextSafe(join(target.dir,'MEMORY.md'))??'').split(/\r?\n/).filter(line=>line.trim().startsWith('- [')&&line.includes(target.supersedes));if(hits.length!==1)throw Error('memory-native-supersedes-not-unique')
|
|
1783
1822
|
const compiled=prepareValueRevision(target,sourceRecords,hits[0].trim())
|
|
@@ -1946,6 +1985,7 @@ function defineSearchTool(ctx) {
|
|
|
1946
1985
|
name: 'memory_search',
|
|
1947
1986
|
description:
|
|
1948
1987
|
'在记忆索引与主题文件里检索。默认 ranked 支持中英多词问题与有限英文词形归并;exact 用于精确子串定位;' +
|
|
1988
|
+
'默认隐藏已识别的个人敏感内容。用户询问相关资料时才设includePrivate=true;返回内容会进入当前会话日志和模型请求,不能声称只在本地读取。' +
|
|
1949
1989
|
'默认同时查当前项目和全局偏好,不查其他项目;可指定单库。view=history显式查询带来源的旧值、取代与移出记录,返回历史身份及覆盖范围,不能当当前指令。',
|
|
1950
1990
|
parameters: {
|
|
1951
1991
|
type: 'object',
|
|
@@ -1953,6 +1993,7 @@ function defineSearchTool(ctx) {
|
|
|
1953
1993
|
required: ['query'],
|
|
1954
1994
|
properties: {
|
|
1955
1995
|
query: { type: 'string', description: '检索词,尽量具体(≤200 字);也可给返回的完整64位recordId精确定位来源条目,不能用8位索引id' },
|
|
1996
|
+
includePrivate:{type:'boolean',description:'仅在用户询问相关个人资料时明确设true,允许读取被自动降载的个人内容。默认false;不是文件访问权限或完整隐私识别器。'},
|
|
1956
1997
|
mode: { type: 'string', enum: ['exact', 'ranked'], description: 'ranked 默认多词排序;exact 精确定位。不是语义向量检索,不支持完整同义词或英文词形分析' },
|
|
1957
1998
|
view:{type:'string',enum:['current','history'],description:'current默认只查当前视图;history查受管历史档案(已撤回来源仍不可见)。旧日志不会被伪造成完整历史。'},
|
|
1958
1999
|
atSequence:{type:'integer',description:'仅history:按选定单库的记录序号查询当时有效的条目,必须指定scope=project或global;不是跨库统一版本。'},
|
|
@@ -2000,10 +2041,10 @@ function defineSearchTool(ctx) {
|
|
|
2000
2041
|
return searchScopedStores([
|
|
2001
2042
|
{ dir: resolveStoreDir(ctx, exec, 'memory_search', 'project'), scope: 'project' },
|
|
2002
2043
|
{ dir: resolveStoreDir(ctx, exec, 'memory_search', 'global'), scope: 'global' },
|
|
2003
|
-
], args.query, { limit: args.limit, mode: args.mode, context:args.context,task:args.task,view:args.view,atSequence:args.atSequence,asOf:args.asOf })
|
|
2044
|
+
], args.query, { includePrivate:args.includePrivate,limit: args.limit, mode: args.mode, context:args.context,task:args.task,view:args.view,atSequence:args.atSequence,asOf:args.asOf })
|
|
2004
2045
|
}
|
|
2005
2046
|
const dir = resolveStoreDir(ctx, exec, 'memory_search', args.scope)
|
|
2006
|
-
return searchStore(dir, args.query, { limit: args.limit, mode: args.mode, context:args.context,task:args.task,view:args.view,atSequence:args.atSequence,asOf:args.asOf })
|
|
2047
|
+
return searchStore(dir, args.query, { includePrivate:args.includePrivate,limit: args.limit, mode: args.mode, context:args.context,task:args.task,view:args.view,atSequence:args.atSequence,asOf:args.asOf })
|
|
2007
2048
|
},
|
|
2008
2049
|
}
|
|
2009
2050
|
}
|
|
@@ -2134,6 +2175,29 @@ function defineStatusTool(ctx, sourceInputs) {
|
|
|
2134
2175
|
expired: { type: 'integer' },
|
|
2135
2176
|
duplicateGroups: { type: 'integer' },
|
|
2136
2177
|
storeBytes: { type: 'integer' },
|
|
2178
|
+
// L0 检测摘要:只给计数与检查项;明细走 `node scripts/detect.mjs --json`。
|
|
2179
|
+
lint: {
|
|
2180
|
+
type: 'object',
|
|
2181
|
+
additionalProperties: false,
|
|
2182
|
+
required: ['errors', 'warnings', 'checks'],
|
|
2183
|
+
properties: {
|
|
2184
|
+
errors: { type: 'integer' },
|
|
2185
|
+
warnings: { type: 'integer' },
|
|
2186
|
+
checks: {
|
|
2187
|
+
type: 'array',
|
|
2188
|
+
items: {
|
|
2189
|
+
type: 'object',
|
|
2190
|
+
additionalProperties: false,
|
|
2191
|
+
required: ['id', 'severity', 'count'],
|
|
2192
|
+
properties: {
|
|
2193
|
+
id: { type: 'string' },
|
|
2194
|
+
severity: { type: 'string', enum: ['error', 'warning'] },
|
|
2195
|
+
count: { type: 'integer' },
|
|
2196
|
+
},
|
|
2197
|
+
},
|
|
2198
|
+
},
|
|
2199
|
+
},
|
|
2200
|
+
},
|
|
2137
2201
|
sourceLedger: { type: 'object', additionalProperties: false,
|
|
2138
2202
|
required: ['available', 'fullLimit', 'pendingLimit', 'retiredLimit', 'byteLimit'],
|
|
2139
2203
|
properties: { available: { type: 'boolean' }, fullRecords: { type: 'integer' }, retiredRecords: { type: 'integer' }, pending: { type: 'integer' }, bytes: { type: 'integer' }, fullLimit: { type: 'integer' }, pendingLimit: { type: 'integer' }, retiredLimit: { type: 'integer' }, byteLimit: { type: 'integer' }, reason: { type: 'string', enum: ['source-ledger-unavailable'] } } },
|
|
@@ -2160,7 +2224,8 @@ function defineStatusTool(ctx, sourceInputs) {
|
|
|
2160
2224
|
text:
|
|
2161
2225
|
`索引 ${value.index.lines}/${value.index.limitLines} 行、${value.index.bytes}/${value.index.limitBytes} 字节;` +
|
|
2162
2226
|
`类型:${types};过期 ${value.expired} 条;重复组 ${value.duplicateGroups};` +
|
|
2163
|
-
`主题文件:${topics || '无'};库占用 ${(value.storeBytes / 1024).toFixed(1)}K
|
|
2227
|
+
`主题文件:${topics || '无'};库占用 ${(value.storeBytes / 1024).toFixed(1)}K。` +
|
|
2228
|
+
(value.lint ? `\n检测(L0):error ${value.lint.errors}、warning ${value.lint.warnings}` + (value.lint.checks.length ? ';' + value.lint.checks.map((check) => `${check.id}×${check.count}`).join('、') : '') + '(明细:node scripts/detect.mjs)' : '') + '\n' +
|
|
2164
2229
|
(value.sourceLedger?.available ? `来源记录 ${value.sourceLedger.fullRecords}/${value.sourceLedger.fullLimit};历史来源凭据 ${value.sourceLedger.retiredRecords}/${value.sourceLedger.retiredLimit};待审 ${value.sourceLedger.pending}/${value.sourceLedger.pendingLimit};来源占用 ${(value.sourceLedger.bytes / 1024).toFixed(1)}/${value.sourceLedger.byteLimit / 1024}K。\n` : '来源账本待修复,容量状态未知。\n') + value.dir+(value.capture?'\n捕获诊断(全局保留作业):'+(!value.capture.available?'账本不可用,未知':value.capture.latest?.diagnostic?value.capture.latest.diagnostic.classification+';解析拒绝'+value.capture.latest.diagnostic.parserRejected+',截断'+value.capture.latest.diagnostic.deferred+',准入拒绝'+value.capture.latest.diagnostic.admissionRejected+',写入失败'+value.capture.latest.diagnostic.writeFailures+';不证明没有漏记':value.capture.latest?'旧作业无细分诊断或仍未完成,不能推断空结果':'尚无捕获作业记录;不能推断没有长期信息'):'')+(value.capture?.blockedInput?'\n自动整理未执行:用户来源不完整;没有从截断的前半段建立记忆。':'')+(value.executionObservations?'\n可引用执行结果(复制callId及原文):\n'+value.executionObservations.items.map(item=>JSON.stringify(item)).join('\n')+'\n'+value.executionObservations.note+(value.executionObservations.truncated?'(列表有省略,优先核对最近结果)':''):'') ,
|
|
2165
2230
|
},
|
|
2166
2231
|
]
|
|
@@ -2169,6 +2234,7 @@ function defineStatusTool(ctx, sourceInputs) {
|
|
|
2169
2234
|
async execute(args, exec) {
|
|
2170
2235
|
const dir = resolveStoreDir(ctx, exec, 'memory_status', args.scope)
|
|
2171
2236
|
const value={...statusOf(dir),capture:managedRead(storeRoot(),()=>captureJobStatus(storeRoot()))}
|
|
2237
|
+
value.lint = await lintStatus(dir, dir === storeRoot() ? 'global' : 'project')
|
|
2172
2238
|
if(args.includeObservations!==undefined&&typeof args.includeObservations!=='boolean')throw Error('memory-observation-invalid-list-option')
|
|
2173
2239
|
if(args.includeObservations===true){if(!captureSessionEligible(exec?.agent?.session))throw Error('memory-observation-source-unavailable');return{...value,executionObservations:sourceInputs.availableForExecution(exec)}}
|
|
2174
2240
|
return value
|
|
@@ -2196,7 +2262,7 @@ function defineStatusTool(ctx, sourceInputs) {
|
|
|
2196
2262
|
if(args.scope!=='both')return singleExecute(args,exec)
|
|
2197
2263
|
if(args.includeObservations!==undefined&&typeof args.includeObservations!=='boolean')throw Error('memory-observation-invalid-list-option')
|
|
2198
2264
|
const root=storeRoot()
|
|
2199
|
-
|
|
2265
|
+
const result=managedRead(root,()=>{
|
|
2200
2266
|
const stores=[{scope:'global',available:true,status:statusOf(root)}];let project
|
|
2201
2267
|
if(!exec?.agent||typeof ctx.workingDirectory?.get!=='function')project={scope:'project',available:false,reason:'no-current-project'}
|
|
2202
2268
|
else{
|
|
@@ -2212,10 +2278,14 @@ function defineStatusTool(ctx, sourceInputs) {
|
|
|
2212
2278
|
}catch{project={scope:'project',available:false,reason:'project-status-unavailable'}}
|
|
2213
2279
|
}
|
|
2214
2280
|
stores.push(project)
|
|
2215
|
-
|
|
2216
|
-
if(args.includeObservations===true){if(!captureSessionEligible(exec?.agent?.session))throw Error('memory-observation-source-unavailable');value.executionObservations=sourceInputs.availableForExecution(exec)}
|
|
2217
|
-
return value
|
|
2281
|
+
return {scope:'both',stores,capture:captureJobStatus(root)}
|
|
2218
2282
|
})
|
|
2283
|
+
for(const row of result.stores){
|
|
2284
|
+
if(!row.available)continue
|
|
2285
|
+
row.status.lint=await lintStatus(row.status.dir,row.scope)
|
|
2286
|
+
}
|
|
2287
|
+
if(args.includeObservations===true){if(!captureSessionEligible(exec?.agent?.session))throw Error('memory-observation-source-unavailable');result.executionObservations=sourceInputs.availableForExecution(exec)}
|
|
2288
|
+
return result
|
|
2219
2289
|
}
|
|
2220
2290
|
return definition
|
|
2221
2291
|
}
|
|
@@ -2255,7 +2325,7 @@ function defineForgetTool(ctx) {
|
|
|
2255
2325
|
text:
|
|
2256
2326
|
value.removed === 0
|
|
2257
2327
|
? `没有匹配到任何索引行:${value.path}`
|
|
2258
|
-
:
|
|
2328
|
+
: `已停止使用 ${value.removed} 条索引记忆(${value.path})。原话、主题正文、会话日志、备份及已发送内容未由此清除;这不是历史数据擦除。`,
|
|
2259
2329
|
},
|
|
2260
2330
|
],
|
|
2261
2331
|
},
|
|
@@ -2430,13 +2500,14 @@ function setupAutoCapture(ctx, config) {
|
|
|
2430
2500
|
const captureDirs=[storeRoot(),projectDir].filter(Boolean)
|
|
2431
2501
|
const memorySnapshot=managedReadMany(captureDirs,()=>{
|
|
2432
2502
|
const stores=captureDirs.map(dir=>{const scope=dir===storeRoot()?'global':'project',policy=withdrawalPolicy(dir);return{dir,scope,policy,records:effectiveSourceRecords(dir,scope,undefined,true),indexLines:filterWithdrawn(readTextSafe(join(dir,'MEMORY.md'))??'',policy,true).split('\n').map(line=>line.trim()).filter(line=>line.startsWith('- [')).slice(-60)}})
|
|
2433
|
-
const
|
|
2503
|
+
for(const store of stores)store.indexLines=publicMemoryIndex(store.indexLines,store.records)
|
|
2504
|
+
const projections=stores.flatMap(store=>publicMemoryRecords(store.records).flatMap(record=>{
|
|
2434
2505
|
const line=record.indexLine??indexLine(record.type,record.summary,record.expires,record.detail!==undefined)
|
|
2435
2506
|
if(!store.indexLines.includes(line))return[]
|
|
2436
2507
|
const topic=filterWithdrawn(readTextSafe(join(store.dir,record.type+'.md'))??'',store.policy)
|
|
2437
2508
|
return[captureProjection(record,store.scope,`[${store.scope}] ${line}`,topic)]
|
|
2438
2509
|
})).slice(-60)
|
|
2439
|
-
return{validationRecords:stores.flatMap(store=>validationCurrentRecords(store.dir,store.scope,store.records)),sourceRecords:stores.flatMap(store=>store.records),structuredRecords:projections,relationTargets:stores.flatMap(store=>store.records.filter(record=>['claim','belief'].includes(record.meaning?.kind)&&!record.meaning.relations?.length).map(record=>({scope:store.scope,recordId:record.id,kind:record.meaning.kind,summary:record.summary}))).slice(-60),revisions:new Map(captureDirs.map(dir=>[dir,{value:storeRevision(dir)}])),indexLines:stores.flatMap(store=>store.indexLines.map(line=>`[${store.scope}] ${line}`))}
|
|
2510
|
+
return{validationRecords:stores.flatMap(store=>validationCurrentRecords(store.dir,store.scope,store.records)),sourceRecords:stores.flatMap(store=>store.records),structuredRecords:projections,relationTargets:stores.flatMap(store=>publicMemoryRecords(store.records).filter(record=>['claim','belief'].includes(record.meaning?.kind)&&!record.meaning.relations?.length).map(record=>({scope:store.scope,recordId:record.id,kind:record.meaning.kind,summary:record.summary}))).slice(-60),revisions:new Map(captureDirs.map(dir=>[dir,{value:storeRevision(dir)}])),indexLines:stores.flatMap(store=>store.indexLines.map(line=>`[${store.scope}] ${line}`))}
|
|
2440
2511
|
})
|
|
2441
2512
|
const revisions=memorySnapshot.revisions
|
|
2442
2513
|
// 按类型分库:跨项目的偏好/纠正进全局库,项目决定进项目库。
|
|
@@ -2722,7 +2793,19 @@ function setupAutoCapture(ctx, config) {
|
|
|
2722
2793
|
rememberSession(session)
|
|
2723
2794
|
scheduleRestore(session)
|
|
2724
2795
|
})
|
|
2725
|
-
ctx.on('session/disposed', session => {
|
|
2796
|
+
ctx.on('session/disposed', session => {
|
|
2797
|
+
// 短会话在结构上永远到不了 everyTurns;把“没整理”记成可观测事件,而不是静默丢弃。
|
|
2798
|
+
const state = sessions.get(session?.id)
|
|
2799
|
+
if (state && state.turns > 0 && state.turns < options.everyTurns && !state.running) {
|
|
2800
|
+
try {
|
|
2801
|
+
appendAudit(storeRoot(), { op: 'capture', outcome: 'skipped', reason: 'short-session-below-threshold', sessionId: session.id, turns: state.turns, everyTurns: options.everyTurns })
|
|
2802
|
+
} catch {
|
|
2803
|
+
/* 状态卸载路径上的审计是尽力而为,不能阻断 */
|
|
2804
|
+
}
|
|
2805
|
+
}
|
|
2806
|
+
observedSessions.delete(session.id)
|
|
2807
|
+
sessions.delete(session.id)
|
|
2808
|
+
})
|
|
2726
2809
|
|
|
2727
2810
|
queryService = watchOptionalService(ctx, 'sessionQuery', state => {
|
|
2728
2811
|
const available = typeof state.value?.observeSession === 'function'
|
|
@@ -2798,12 +2881,18 @@ export function apply(ctx, config = {}) {
|
|
|
2798
2881
|
}
|
|
2799
2882
|
}
|
|
2800
2883
|
|
|
2884
|
+
const history = setupMemoryHistory(ctx, renderForRuntime)
|
|
2885
|
+
// The host waits for apply(): no contexts, tools or success marker are
|
|
2886
|
+
// published until an asynchronous projection registration has succeeded.
|
|
2887
|
+
return typeof history?.then === 'function' ? history.then(activate) : activate(history)
|
|
2888
|
+
|
|
2889
|
+
function activate(memoryHistory) {
|
|
2890
|
+
if (ctx.fiber?.uid === null) return
|
|
2801
2891
|
let calls = 0
|
|
2802
|
-
const memoryHistory = setupMemoryHistory(ctx, renderForRuntime)
|
|
2803
2892
|
|
|
2804
2893
|
ctx.systemPrompt.context({
|
|
2805
2894
|
name: 'memory:protocol', order: CONTEXT_ORDER - 1, required: true,
|
|
2806
|
-
interpolate: false, text: context => memoryProtocol(ctx, context),
|
|
2895
|
+
interpolate: false, text: context => memoryProtocol(ctx, context)+'\n'+PRIVATE_MEMORY_NOTICE,
|
|
2807
2896
|
})
|
|
2808
2897
|
|
|
2809
2898
|
ctx.systemPrompt.context({
|
|
@@ -2904,6 +2993,7 @@ export function apply(ctx, config = {}) {
|
|
|
2904
2993
|
} catch {
|
|
2905
2994
|
/* 写不出来就算了:注入不依赖这两个文件 */
|
|
2906
2995
|
}
|
|
2996
|
+
}
|
|
2907
2997
|
}
|
|
2908
2998
|
|
|
2909
2999
|
installManagedMemoryInternals({indexLine,clearCache:()=>cache.clear(),storeRevision:storeRevisionLocal,withdrawManagedSourceKey:withdrawManagedSourceKeyLocal,recoverMemoryPublication:recoverMemoryPublicationLocal})
|
package/managed-policy.mjs
CHANGED
|
@@ -68,7 +68,9 @@ function openDb(paths,{write=false,requireExisting=false}={}){
|
|
|
68
68
|
}
|
|
69
69
|
const before=lstatSync(path);let db
|
|
70
70
|
try{
|
|
71
|
-
|
|
71
|
+
// Managed reads share the writer lock. Let brief contention clear without
|
|
72
|
+
// releasing transaction ownership or waiting indefinitely.
|
|
73
|
+
db=new DatabaseSync(path,{readOnly:!write});db.exec('PRAGMA trusted_schema=OFF; PRAGMA busy_timeout=750;')
|
|
72
74
|
const now=lstatSync(path);if(now.isSymbolicLink()||now.ino!==before.ino||now.dev!==before.dev)fail('changed-database-file')
|
|
73
75
|
if(created){db.exec('BEGIN IMMEDIATE; '+SCHEMA+'; PRAGMA application_id='+APPLICATION_ID+'; PRAGMA user_version=1; COMMIT;')}
|
|
74
76
|
schema(db)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "solopup-memory",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.22.0-beta.3",
|
|
4
4
|
"description": "SoloPup Memory — source-linked, layered text memory for DeepSeek Harness. Public beta.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.mjs",
|
|
@@ -25,129 +25,145 @@
|
|
|
25
25
|
"CHANGELOG.md",
|
|
26
26
|
"scripts/",
|
|
27
27
|
"COMPATIBILITY.md",
|
|
28
|
-
"test.mjs",
|
|
29
|
-
"test-security.mjs",
|
|
30
|
-
"test-adversarial.mjs",
|
|
31
|
-
"test-concurrency.mjs",
|
|
32
|
-
"test-supersede.mjs",
|
|
33
|
-
"test-history.mjs",
|
|
34
|
-
"test-smell.mjs",
|
|
35
|
-
"test-links.mjs",
|
|
36
|
-
"test-packaging.mjs",
|
|
37
|
-
"test-patch.mjs",
|
|
38
|
-
"test-compat.mjs",
|
|
28
|
+
"test/test.mjs",
|
|
29
|
+
"test/test-security.mjs",
|
|
30
|
+
"test/test-adversarial.mjs",
|
|
31
|
+
"test/test-concurrency.mjs",
|
|
32
|
+
"test/test-supersede.mjs",
|
|
33
|
+
"test/test-history.mjs",
|
|
34
|
+
"test/test-smell.mjs",
|
|
35
|
+
"test/test-links.mjs",
|
|
36
|
+
"test/test-packaging.mjs",
|
|
37
|
+
"test/test-patch.mjs",
|
|
38
|
+
"test/test-compat.mjs",
|
|
39
39
|
"accept.mjs",
|
|
40
40
|
"worker-write.mjs",
|
|
41
|
-
"test-conflict.mjs",
|
|
42
|
-
"test-usability.mjs",
|
|
43
|
-
"test-compaction-compat.mjs",
|
|
44
|
-
"test-schema.mjs",
|
|
41
|
+
"test/test-conflict.mjs",
|
|
42
|
+
"test/test-usability.mjs",
|
|
43
|
+
"test/test-compaction-compat.mjs",
|
|
44
|
+
"test/test-schema.mjs",
|
|
45
45
|
"scripts/probe-load.mjs",
|
|
46
46
|
"capture.mjs",
|
|
47
47
|
"capture-llm.mjs",
|
|
48
48
|
"capture-evidence.mjs",
|
|
49
49
|
"capture-revision.mjs",
|
|
50
|
-
"test-capture-revision.mjs",
|
|
51
|
-
"test-capture.mjs",
|
|
52
|
-
"test-paired-analysis.mjs",
|
|
50
|
+
"test/test-capture-revision.mjs",
|
|
51
|
+
"test/test-capture.mjs",
|
|
52
|
+
"test/test-paired-analysis.mjs",
|
|
53
53
|
"retrieval.mjs",
|
|
54
|
-
"test-retrieval.mjs",
|
|
54
|
+
"test/test-retrieval.mjs",
|
|
55
55
|
"candidates.mjs",
|
|
56
|
-
"test-candidates.mjs",
|
|
56
|
+
"test/test-candidates.mjs",
|
|
57
57
|
"publication.mjs",
|
|
58
|
-
"test-publication.mjs",
|
|
58
|
+
"test/test-publication.mjs",
|
|
59
59
|
"withdrawal.mjs",
|
|
60
|
-
"test-withdrawal.mjs",
|
|
60
|
+
"test/test-withdrawal.mjs",
|
|
61
61
|
"capture-jobs.mjs",
|
|
62
|
-
"test-capture-jobs.mjs",
|
|
62
|
+
"test/test-capture-jobs.mjs",
|
|
63
63
|
"context-history.mjs",
|
|
64
|
-
"test-context-history.mjs",
|
|
64
|
+
"test/test-context-history.mjs",
|
|
65
65
|
"capture-inputs.mjs",
|
|
66
|
-
"test-capture-inputs.mjs",
|
|
67
|
-
"test-inline-summary.mjs",
|
|
66
|
+
"test/test-capture-inputs.mjs",
|
|
67
|
+
"test/test-inline-summary.mjs",
|
|
68
68
|
"managed-logs.mjs",
|
|
69
|
-
"test-withdrawal-archives.mjs",
|
|
69
|
+
"test/test-withdrawal-archives.mjs",
|
|
70
70
|
"cordis.patch.yml",
|
|
71
71
|
"plugin-config.mjs",
|
|
72
72
|
"host-services.mjs",
|
|
73
|
-
"test-plugin-contract.mjs",
|
|
73
|
+
"test/test-plugin-contract.mjs",
|
|
74
74
|
"project-stores.mjs",
|
|
75
|
-
"test-project-stores.mjs",
|
|
75
|
+
"test/test-project-stores.mjs",
|
|
76
76
|
"service-readiness.mjs",
|
|
77
|
-
"test-service-readiness.mjs",
|
|
77
|
+
"test/test-service-readiness.mjs",
|
|
78
78
|
"tool-inputs.mjs",
|
|
79
79
|
"fixture-host.mjs",
|
|
80
|
-
"test-source-key.mjs",
|
|
81
|
-
"test-tool-inputs.mjs",
|
|
82
|
-
"test-tool-write-lifecycle.mjs",
|
|
83
|
-
"test-tool-write-guard.mjs",
|
|
80
|
+
"test/test-source-key.mjs",
|
|
81
|
+
"test/test-tool-inputs.mjs",
|
|
82
|
+
"test/test-tool-write-lifecycle.mjs",
|
|
83
|
+
"test/test-tool-write-guard.mjs",
|
|
84
84
|
"source-retirement.mjs",
|
|
85
|
-
"test-source-retirement.mjs",
|
|
85
|
+
"test/test-source-retirement.mjs",
|
|
86
86
|
"managed-policy.mjs",
|
|
87
87
|
"managed-hooks.mjs",
|
|
88
88
|
"managed-access.mjs",
|
|
89
89
|
"store-lock-guard.mjs",
|
|
90
|
-
"test-managed-access.mjs",
|
|
90
|
+
"test/test-managed-access.mjs",
|
|
91
91
|
"managed-activation.mjs",
|
|
92
|
-
"test-managed-activation.mjs",
|
|
92
|
+
"test/test-managed-activation.mjs",
|
|
93
93
|
"runtime-startup.mjs",
|
|
94
|
-
"test-runtime-startup.mjs",
|
|
94
|
+
"test/test-runtime-startup.mjs",
|
|
95
95
|
"meaning.mjs",
|
|
96
|
-
"test-meaning.mjs",
|
|
96
|
+
"test/test-meaning.mjs",
|
|
97
97
|
"episodes.mjs",
|
|
98
98
|
"source-record.mjs",
|
|
99
|
-
"test-episodes.mjs",
|
|
99
|
+
"test/test-episodes.mjs",
|
|
100
100
|
"belief-revision.mjs",
|
|
101
|
-
"test-belief-revision.mjs",
|
|
101
|
+
"test/test-belief-revision.mjs",
|
|
102
102
|
"tool-observations.mjs",
|
|
103
|
-
"test-tool-observations.mjs",
|
|
103
|
+
"test/test-tool-observations.mjs",
|
|
104
104
|
"capture-diagnostics.mjs",
|
|
105
|
-
"test-capture-diagnostics.mjs",
|
|
105
|
+
"test/test-capture-diagnostics.mjs",
|
|
106
106
|
"snapshots.mjs",
|
|
107
|
-
"test-snapshots.mjs",
|
|
107
|
+
"test/test-snapshots.mjs",
|
|
108
108
|
"restore.mjs",
|
|
109
109
|
"restoration-lock.mjs",
|
|
110
|
-
"test-restore.mjs",
|
|
111
|
-
"test-status-both.mjs",
|
|
112
|
-
"test-text-admission.mjs",
|
|
110
|
+
"test/test-restore.mjs",
|
|
111
|
+
"test/test-status-both.mjs",
|
|
112
|
+
"test/test-text-admission.mjs",
|
|
113
113
|
"memory-policy.mjs",
|
|
114
114
|
"capture-submission.mjs",
|
|
115
|
-
"test-capture-submission.mjs",
|
|
115
|
+
"test/test-capture-submission.mjs",
|
|
116
116
|
"capture-projections.mjs",
|
|
117
|
-
"test-capture-projections.mjs",
|
|
117
|
+
"test/test-capture-projections.mjs",
|
|
118
118
|
"capture-validation-contract.mjs",
|
|
119
119
|
"capture-validation.mjs",
|
|
120
|
-
"test-capture-validation.mjs",
|
|
120
|
+
"test/test-capture-validation.mjs",
|
|
121
121
|
"capture-validation-job.mjs",
|
|
122
|
-
"test-capture-validation-job.mjs",
|
|
123
|
-
"test-capture-validation-flow.mjs",
|
|
124
|
-
"test-capture-validation-lineage.mjs",
|
|
122
|
+
"test/test-capture-validation-job.mjs",
|
|
123
|
+
"test/test-capture-validation-flow.mjs",
|
|
124
|
+
"test/test-capture-validation-lineage.mjs",
|
|
125
125
|
"native-write-validation.mjs",
|
|
126
|
-
"test-native-write-validation.mjs",
|
|
127
|
-
"test-native-service-lifecycle.mjs",
|
|
126
|
+
"test/test-native-write-validation.mjs",
|
|
127
|
+
"test/test-native-service-lifecycle.mjs",
|
|
128
128
|
"field-lineage.mjs",
|
|
129
|
-
"test-field-lineage.mjs",
|
|
130
|
-
"test-capture-field-lineage.mjs",
|
|
129
|
+
"test/test-field-lineage.mjs",
|
|
130
|
+
"test/test-capture-field-lineage.mjs",
|
|
131
131
|
"validation-transition-context.mjs",
|
|
132
|
-
"test-validation-transition-context.mjs",
|
|
132
|
+
"test/test-validation-transition-context.mjs",
|
|
133
133
|
"memory-scope-policy.mjs",
|
|
134
134
|
"control-schema.mjs",
|
|
135
|
-
"test-control-schema.mjs",
|
|
135
|
+
"test/test-control-schema.mjs",
|
|
136
136
|
"revision-admission.mjs",
|
|
137
|
-
"test-revision-admission.mjs",
|
|
137
|
+
"test/test-revision-admission.mjs",
|
|
138
138
|
"memory-rule-policy.mjs",
|
|
139
|
-
"test-rule-admission.mjs",
|
|
140
|
-
"test-validation-source-refs.mjs",
|
|
141
|
-
"test-source-completeness.mjs",
|
|
139
|
+
"test/test-rule-admission.mjs",
|
|
140
|
+
"test/test-validation-source-refs.mjs",
|
|
141
|
+
"test/test-source-completeness.mjs",
|
|
142
142
|
"source-identity.mjs",
|
|
143
|
-
"test-legacy-source-identity.mjs",
|
|
143
|
+
"test/test-legacy-source-identity.mjs",
|
|
144
144
|
"icon.svg",
|
|
145
145
|
"locale/",
|
|
146
146
|
"README.en.md",
|
|
147
147
|
"RELEASE.md",
|
|
148
148
|
"memory-protocol.mjs",
|
|
149
149
|
"capture-source-aliases.mjs",
|
|
150
|
-
"test-explicit-memory.mjs"
|
|
150
|
+
"test/test-explicit-memory.mjs",
|
|
151
|
+
"privacy.mjs",
|
|
152
|
+
"test/test-privacy.mjs",
|
|
153
|
+
"detect.mjs",
|
|
154
|
+
"scripts/detect.mjs",
|
|
155
|
+
"scripts/telemetry.mjs",
|
|
156
|
+
"scripts/dream.mjs",
|
|
157
|
+
"eval/semantic-suite.mjs",
|
|
158
|
+
"eval/semantic/cases.json",
|
|
159
|
+
"eval/bench-detect.mjs",
|
|
160
|
+
"test/test-detect.mjs",
|
|
161
|
+
"test/test-telemetry.mjs",
|
|
162
|
+
"test/test-semantic-suite.mjs",
|
|
163
|
+
"test/test-dream-plan.mjs",
|
|
164
|
+
"DETECTION.md",
|
|
165
|
+
"DREAMING-DESIGN.md",
|
|
166
|
+
"test/test-dsh-registration.mjs"
|
|
151
167
|
],
|
|
152
168
|
"engines": {
|
|
153
169
|
"node": ">=24.9",
|
|
@@ -160,7 +176,7 @@
|
|
|
160
176
|
},
|
|
161
177
|
"license": "MIT",
|
|
162
178
|
"scripts": {
|
|
163
|
-
"test": "node --test --test-concurrency=4 test.mjs test-security.mjs test-adversarial.mjs test-concurrency.mjs test-supersede.mjs test-history.mjs test-smell.mjs test-links.mjs test-packaging.mjs test-patch.mjs test-compat.mjs test-conflict.mjs test-usability.mjs test-compaction-compat.mjs test-schema.mjs test-capture.mjs test-paired-analysis.mjs test-retrieval.mjs test-candidates.mjs test-publication.mjs test-withdrawal.mjs test-capture-jobs.mjs test-context-history.mjs test-capture-inputs.mjs test-inline-summary.mjs test-withdrawal-archives.mjs test-plugin-contract.mjs test-project-stores.mjs test-service-readiness.mjs test-source-key.mjs test-tool-inputs.mjs test-tool-write-lifecycle.mjs test-tool-write-guard.mjs test-source-retirement.mjs test-managed-access.mjs test-managed-activation.mjs test-runtime-startup.mjs test-capture-revision.mjs test-meaning.mjs test-episodes.mjs test-belief-revision.mjs test-tool-observations.mjs test-capture-diagnostics.mjs test-snapshots.mjs test-restore.mjs test-status-both.mjs test-text-admission.mjs test-capture-submission.mjs test-capture-projections.mjs test-capture-validation.mjs test-capture-validation-job.mjs test-capture-validation-flow.mjs test-capture-validation-lineage.mjs test-native-write-validation.mjs test-native-service-lifecycle.mjs test-field-lineage.mjs test-capture-field-lineage.mjs test-validation-transition-context.mjs test-control-schema.mjs test-revision-admission.mjs test-rule-admission.mjs test-validation-source-refs.mjs test-source-completeness.mjs test-legacy-source-identity.mjs test-explicit-memory.mjs",
|
|
179
|
+
"test": "node --test --test-concurrency=4 test/test.mjs test/test-security.mjs test/test-adversarial.mjs test/test-concurrency.mjs test/test-supersede.mjs test/test-history.mjs test/test-smell.mjs test/test-links.mjs test/test-packaging.mjs test/test-patch.mjs test/test-compat.mjs test/test-conflict.mjs test/test-usability.mjs test/test-compaction-compat.mjs test/test-schema.mjs test/test-capture.mjs test/test-paired-analysis.mjs test/test-retrieval.mjs test/test-candidates.mjs test/test-publication.mjs test/test-withdrawal.mjs test/test-capture-jobs.mjs test/test-context-history.mjs test/test-capture-inputs.mjs test/test-inline-summary.mjs test/test-withdrawal-archives.mjs test/test-plugin-contract.mjs test/test-project-stores.mjs test/test-service-readiness.mjs test/test-source-key.mjs test/test-tool-inputs.mjs test/test-tool-write-lifecycle.mjs test/test-tool-write-guard.mjs test/test-source-retirement.mjs test/test-managed-access.mjs test/test-managed-activation.mjs test/test-runtime-startup.mjs test/test-capture-revision.mjs test/test-meaning.mjs test/test-episodes.mjs test/test-belief-revision.mjs test/test-tool-observations.mjs test/test-capture-diagnostics.mjs test/test-snapshots.mjs test/test-restore.mjs test/test-status-both.mjs test/test-text-admission.mjs test/test-capture-submission.mjs test/test-capture-projections.mjs test/test-capture-validation.mjs test/test-capture-validation-job.mjs test/test-capture-validation-flow.mjs test/test-capture-validation-lineage.mjs test/test-native-write-validation.mjs test/test-native-service-lifecycle.mjs test/test-field-lineage.mjs test/test-capture-field-lineage.mjs test/test-validation-transition-context.mjs test/test-control-schema.mjs test/test-revision-admission.mjs test/test-rule-admission.mjs test/test-validation-source-refs.mjs test/test-source-completeness.mjs test/test-legacy-source-identity.mjs test/test-explicit-memory.mjs test/test-privacy.mjs test/test-detect.mjs test/test-telemetry.mjs test/test-semantic-suite.mjs test/test-dream-plan.mjs test/test-dsh-registration.mjs",
|
|
164
180
|
"eval": "node eval/run-eval.mjs",
|
|
165
181
|
"gate": "node eval/run-eval.mjs --check",
|
|
166
182
|
"verify": "node scripts/verify.mjs",
|
|
@@ -170,7 +186,14 @@
|
|
|
170
186
|
"probe:package": "node scripts/probe-package.mjs",
|
|
171
187
|
"projects": "node scripts/projects.mjs",
|
|
172
188
|
"control": "node scripts/control.mjs",
|
|
173
|
-
"backup": "node scripts/backup.mjs"
|
|
189
|
+
"backup": "node scripts/backup.mjs",
|
|
190
|
+
"detect": "node scripts/detect.mjs",
|
|
191
|
+
"telemetry": "node scripts/telemetry.mjs",
|
|
192
|
+
"dream": "node scripts/dream.mjs",
|
|
193
|
+
"semantic": "node eval/semantic-suite.mjs --verbose",
|
|
194
|
+
"security": "node scripts/security-check.mjs",
|
|
195
|
+
"soak": "node scripts/soak.mjs",
|
|
196
|
+
"probe:history": "node scripts/probe-history.mjs"
|
|
174
197
|
},
|
|
175
198
|
"dshMemoryRestoreProtocol": 1,
|
|
176
199
|
"dshMemoryDataSchemas": {
|