memorio 5.1.4 → 5.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +21 -12
- package/CHANGELOG.md +18 -6
- package/README.md +44 -7
- package/SECURITY-HARDENING.md +258 -0
- package/SECURITY.md +67 -3
- package/SUMMARY.md +55 -59
- package/adr/002-observer-semantics.md +1 -1
- package/adr/003-deep-mutation-semantics.md +1 -1
- package/adr/004-array-mutation-semantics.md +1 -1
- package/adr/010-logic-phase-0.md +42 -0
- package/adr/README.md +16 -11
- package/bin/cli.js +82 -60
- package/examples/acquired-knowledge.ts +174 -0
- package/examples/agent-memory-demo.ts +140 -0
- package/examples/sync.ts +90 -90
- package/examples/useObserver.tsx +2 -2
- package/global.cjs +1995 -124
- package/global.js +1990 -125
- package/index.cjs +1995 -124
- package/index.d.ts +1 -0
- package/index.js +1990 -125
- package/llms.txt +122 -4
- package/markdown/EXTENSION_VSCODE_DESIGN.md +410 -0
- package/markdown/LOGIC.md +100 -0
- package/markdown/MEMORY-ATTACHMENT.md +17 -10
- package/markdown/MEMORY.md +378 -15
- package/markdown/MEM_FORMAT.md +313 -0
- package/markdown/STATE.md +27 -3
- package/markdown/SYNC.md +18 -14
- package/markdown/TEMPORAL.md +297 -0
- package/markdown/USEOBSERVER.md +7 -4
- package/modules/redux.cjs +1159 -32
- package/modules/redux.cjs.map +1 -1
- package/modules/redux.js +1158 -32
- package/modules/redux.js.map +1 -1
- package/package.json +14 -5
- package/types/exports.d.ts +47 -3
- package/types/logic.d.ts +79 -0
- package/types/memorio.d.ts +60 -16
- package/types/memory.d.ts +118 -0
- package/types/session.d.ts +1 -4
- package/types/store.d.ts +1 -4
- package/types/temporal.d.ts +95 -0
- package/types/useObserver.d.ts +6 -10
- package/vsix/memorio.vsix +0 -0
package/SUMMARY.md
CHANGED
|
@@ -1,59 +1,55 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
|
9
|
-
|
|
|
10
|
-
| `
|
|
11
|
-
| `
|
|
12
|
-
| `
|
|
13
|
-
| `
|
|
14
|
-
| `
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
|
19
|
-
|
|
|
20
|
-
| `
|
|
21
|
-
| `
|
|
22
|
-
| `
|
|
23
|
-
| `
|
|
24
|
-
| `
|
|
25
|
-
| `
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
---
|
|
58
|
-
|
|
59
|
-
**Nota di copertura:** ogni doc in `markdown/` ha ora almeno un esempio corrispondente in `examples/`, **tranne** `DEVTOOLS.md`, `DISPATCH.md`, `INSPECT.md`, `LOGGER.md` e `MEMORY-ATTACHMENT.md` - utile saperlo se in futuro vuoi completare anche quelli.
|
|
1
|
+
# Documentation map
|
|
2
|
+
|
|
3
|
+
This index points to the current public documentation shipped with Memorio 5.2.0. Historical and
|
|
4
|
+
proposed documents remain labelled so that design chronology is not confused with current behavior.
|
|
5
|
+
|
|
6
|
+
## Start here
|
|
7
|
+
|
|
8
|
+
| Document | Purpose |
|
|
9
|
+
| --- | --- |
|
|
10
|
+
| [`README.md`](./README.md) | Product overview, first examples, limitations, and reading paths. |
|
|
11
|
+
| [`CURRENT_PROJECT_CHECKPOINT.md`](./CURRENT_PROJECT_CHECKPOINT.md) | Verified state at the 5.2.0 release boundary. |
|
|
12
|
+
| [`CHANGELOG.md`](./CHANGELOG.md) | User-visible release history. |
|
|
13
|
+
| [`SECURITY.md`](./SECURITY.md) | Security model, encryption, and epistemic boundaries. |
|
|
14
|
+
| [`SECURITY-HARDENING.md`](./SECURITY-HARDENING.md) | Deployment and operational hardening guidance. |
|
|
15
|
+
|
|
16
|
+
## Memory, MEM, and Logic
|
|
17
|
+
|
|
18
|
+
| Document | Status and purpose |
|
|
19
|
+
| --- | --- |
|
|
20
|
+
| [`markdown/MEMORY.md`](./markdown/MEMORY.md) | Current memory API, including Acquire → Discover → Project and separate exact applicability selection. |
|
|
21
|
+
| [`markdown/MEM_FORMAT.md`](./markdown/MEM_FORMAT.md) | Current `.mem` ZIP/JSON package, MAP/DATA, integrity, signatures, inspection, and compatibility. |
|
|
22
|
+
| [`markdown/LOGIC.md`](./markdown/LOGIC.md) | Implemented and verified Logic PHASE 0 contract and repository isolation. |
|
|
23
|
+
| [`markdown/MEMORY-ATTACHMENT.md`](./markdown/MEMORY-ATTACHMENT.md) | Proposed attachment design; not implemented. |
|
|
24
|
+
| [`examples/acquired-knowledge.ts`](./examples/acquired-knowledge.ts) | Rerunnable production workflow example with acquisition, discovery, projection, exact selection, refinement, superseding, and current-reality verification. |
|
|
25
|
+
| [`examples/semantic-memory.ts`](./examples/semantic-memory.ts) | Key/value application memory; despite its historical filename, it is not embedding/vector search. |
|
|
26
|
+
|
|
27
|
+
## API references
|
|
28
|
+
|
|
29
|
+
- Core: [`STATE.md`](./markdown/STATE.md), [`OBSERVER.md`](./markdown/OBSERVER.md),
|
|
30
|
+
[`DISPATCH.md`](./markdown/DISPATCH.md), [`HISTORY.md`](./markdown/HISTORY.md), and
|
|
31
|
+
[`TEMPORAL.md`](./markdown/TEMPORAL.md).
|
|
32
|
+
- Storage: [`STORE.md`](./markdown/STORE.md), [`SESSION.md`](./markdown/SESSION.md),
|
|
33
|
+
[`CACHE.md`](./markdown/CACHE.md), [`IDB.md`](./markdown/IDB.md), and
|
|
34
|
+
[`SQLITE.md`](./markdown/SQLITE.md).
|
|
35
|
+
- Integration and runtime: [`IMPORT.md`](./markdown/IMPORT.md), [`PLATFORM.md`](./markdown/PLATFORM.md),
|
|
36
|
+
[`TYPED.md`](./markdown/TYPED.md), [`SCHEMA.md`](./markdown/SCHEMA.md),
|
|
37
|
+
[`USEOBSERVER.md`](./markdown/USEOBSERVER.md), [`REDUX.md`](./markdown/REDUX.md), and
|
|
38
|
+
[`SYNC.md`](./markdown/SYNC.md).
|
|
39
|
+
- Operations: [`INSPECT.md`](./markdown/INSPECT.md), [`DEVTOOLS.md`](./markdown/DEVTOOLS.md), and
|
|
40
|
+
[`LOGGER.md`](./markdown/LOGGER.md).
|
|
41
|
+
|
|
42
|
+
## Decisions and historical material
|
|
43
|
+
|
|
44
|
+
- [`adr/README.md`](./adr/README.md) classifies every ADR as CURRENT or OPEN while retaining its
|
|
45
|
+
original lifecycle status and text.
|
|
46
|
+
- [`markdown/AUDIT-REPORT.md`](./markdown/AUDIT-REPORT.md) is a historical internal 5.1.0 audit, not a
|
|
47
|
+
third-party audit and not the current release checkpoint.
|
|
48
|
+
- [`markdown/EXTENSION_VSCODE_DESIGN.md`](./markdown/EXTENSION_VSCODE_DESIGN.md) records extension
|
|
49
|
+
design material; it is not the authority for the core 5.2.0 runtime.
|
|
50
|
+
|
|
51
|
+
## Examples
|
|
52
|
+
|
|
53
|
+
The [`examples/`](./examples/) directory contains runnable examples for the major public layers. Use
|
|
54
|
+
isolated state for examples that persist data. In particular, do not point examples at a real
|
|
55
|
+
`.memorio/project.mem` or `.memorio/logic/logic.mem` merely for cleanup or demonstration.
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# ADR 010: Logic PHASE 0 Repository Boundary
|
|
2
|
+
|
|
3
|
+
**Status:** Accepted
|
|
4
|
+
|
|
5
|
+
## Context
|
|
6
|
+
|
|
7
|
+
`memorio.logic` needs to persist and select situation/action/outcome experience while reusing the
|
|
8
|
+
existing immutable acquired-claim, revision, MEM package, and selection machinery. Project acquired
|
|
9
|
+
experience already persists in `.memorio/project.mem`. Mixing both domains would couple clearing,
|
|
10
|
+
claim identities, revision validation, and discovery before cross-domain behavior has been designed.
|
|
11
|
+
|
|
12
|
+
PHASE 0 also needs totals across all active Logic claims. A first implementation added `_all` to the
|
|
13
|
+
general selector, but focused verification showed that the sentinel violated exact applicability
|
|
14
|
+
matching, collided with the applicability namespace, and interacted incorrectly with specificity.
|
|
15
|
+
|
|
16
|
+
## Decision
|
|
17
|
+
|
|
18
|
+
- Persist Logic in its own `MemDirectoryKnowledgeRepository` rooted at `.memorio/logic`, with
|
|
19
|
+
`logic.mem` as its writable source.
|
|
20
|
+
- Keep `.memorio/project.mem` and `.memorio/logic/logic.mem` as independent repositories and runtime
|
|
21
|
+
instances.
|
|
22
|
+
- Keep claim identity, provenance, and revision validation repository-local. Do not imply or emulate
|
|
23
|
+
cross-repository revision relationships.
|
|
24
|
+
- Preserve exact structured applicability matching in the shared selector.
|
|
25
|
+
- Compute Logic totals by loading its repository and counting `activeClaims(state)`, not through a
|
|
26
|
+
wildcard query.
|
|
27
|
+
- Expose the PHASE 0 singleton through named exports and `globalThis.memorio.logic`.
|
|
28
|
+
|
|
29
|
+
## Consequences
|
|
30
|
+
|
|
31
|
+
Logic cannot accidentally discover or clear project memory, and project acquired memory cannot
|
|
32
|
+
discover or clear Logic. The shared selector retains one meaning. Totals include active claims at all
|
|
33
|
+
applicability specificities.
|
|
34
|
+
|
|
35
|
+
There is no unified query, revision chain, provenance graph, or composition behavior across the two
|
|
36
|
+
repositories. Adding any of those is a future design decision, not an implied PHASE 0 capability.
|
|
37
|
+
|
|
38
|
+
## Verification
|
|
39
|
+
|
|
40
|
+
`tests/vitest/tests/contracts/adr-010-logic.test.ts` is the compliance suite. It includes the
|
|
41
|
+
mixed-specificity regression added after `_all` was removed. The detailed investigation and
|
|
42
|
+
chronology remain in `.project/phase0-design-verification.md` and `.project/project_history.md`.
|
package/adr/README.md
CHANGED
|
@@ -17,17 +17,22 @@ Decision Records) format. Each decision record answers four questions:
|
|
|
17
17
|
|
|
18
18
|
## Numbering
|
|
19
19
|
|
|
20
|
-
| ADR | Title |
|
|
21
|
-
|
|
22
|
-
| [001](001-state-proxy-model.md) | State Proxy Model | Accepted |
|
|
23
|
-
| [002](002-observer-semantics.md) | Observer Semantics |
|
|
24
|
-
| [003](003-deep-mutation-semantics.md) | Deep Mutation Semantics |
|
|
25
|
-
| [004](004-array-mutation-semantics.md) | Array Mutation Semantics |
|
|
26
|
-
| [005](005-scheduler-contract.md) | Scheduler Contract | Proposed |
|
|
27
|
-
| [006](006-context-isolation.md) | Context Isolation Model | Accepted |
|
|
28
|
-
| [007](007-mutation-records.md) | Mutation Records | Accepted |
|
|
29
|
-
| [008](008-transactions.md) | Transactions | Accepted |
|
|
30
|
-
| [009](009-history-model.md) | History Model (Snapshot/Delta) | Proposed |
|
|
20
|
+
| ADR | Title | Lifecycle status | 5.2.0 classification |
|
|
21
|
+
|-----|-------|------------------|----------------------|
|
|
22
|
+
| [001](001-state-proxy-model.md) | State Proxy Model | Accepted | **CURRENT** |
|
|
23
|
+
| [002](002-observer-semantics.md) | Observer Semantics | Accepted | **CURRENT** |
|
|
24
|
+
| [003](003-deep-mutation-semantics.md) | Deep Mutation Semantics | Accepted | **CURRENT** |
|
|
25
|
+
| [004](004-array-mutation-semantics.md) | Array Mutation Semantics | Accepted | **CURRENT** |
|
|
26
|
+
| [005](005-scheduler-contract.md) | Scheduler Contract | Proposed | **OPEN** — only the documented current microtask behavior is implemented; the configurable scheduler is not |
|
|
27
|
+
| [006](006-context-isolation.md) | Context Isolation Model | Accepted | **CURRENT** |
|
|
28
|
+
| [007](007-mutation-records.md) | Mutation Records | Accepted | **CURRENT** |
|
|
29
|
+
| [008](008-transactions.md) | Transactions | Accepted | **CURRENT** |
|
|
30
|
+
| [009](009-history-model.md) | History Model (Snapshot/Delta) | Proposed | **OPEN** — the document preserves the implemented flat baseline and a future commit model |
|
|
31
|
+
| [010](010-logic-phase-0.md) | Logic PHASE 0 Repository Boundary | Accepted | **CURRENT** |
|
|
32
|
+
|
|
33
|
+
No ADR is classified as **SUPERSEDED** or **HISTORICAL** at this checkpoint. Historical intermediate
|
|
34
|
+
implementation details (notably Logic's rejected `_all` sentinel) remain in the relevant ADR and
|
|
35
|
+
project history, while the accepted decision describes current behavior.
|
|
31
36
|
|
|
32
37
|
## Lifecycle
|
|
33
38
|
|
package/bin/cli.js
CHANGED
|
@@ -1,68 +1,90 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { spawnSync } from 'node:child_process'
|
|
3
|
-
import path from 'node:path'
|
|
4
|
-
import fs from 'node:fs'
|
|
5
|
-
import os from 'node:os'
|
|
6
|
-
import { fileURLToPath } from 'node:url'
|
|
7
|
-
|
|
8
|
-
const __dirname = path.dirname(fileURLToPath(import.meta.url))
|
|
9
|
-
|
|
10
|
-
const args = process.argv.slice(2)
|
|
11
|
-
const command = args[0]
|
|
12
|
-
|
|
2
|
+
import { spawnSync } from 'node:child_process'
|
|
3
|
+
import path from 'node:path'
|
|
4
|
+
import fs from 'node:fs'
|
|
5
|
+
import os from 'node:os'
|
|
6
|
+
import { fileURLToPath } from 'node:url'
|
|
7
|
+
|
|
8
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url))
|
|
9
|
+
|
|
10
|
+
const args = process.argv.slice(2)
|
|
11
|
+
const command = args[0]
|
|
12
|
+
|
|
13
13
|
if (command === 'install-extension') {
|
|
14
|
-
installExtension()
|
|
14
|
+
installExtension()
|
|
15
|
+
} else if (command === 'inspect') {
|
|
16
|
+
inspectMemory(args[1])
|
|
15
17
|
} else {
|
|
16
|
-
console.
|
|
17
|
-
process.exit(command ? 1 : 0)
|
|
18
|
+
console.info('Usage: npx memorio <install-extension|inspect FILE.mem>')
|
|
19
|
+
process.exit(command ? 1 : 0)
|
|
18
20
|
}
|
|
19
21
|
|
|
20
|
-
function
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
console.error('The npm package may be corrupted, or the build did not copy the .vsix into vsix/.');
|
|
26
|
-
process.exit(1);
|
|
22
|
+
async function inspectMemory(file) {
|
|
23
|
+
if (!file) {
|
|
24
|
+
console.error('Usage: npx memorio inspect FILE.mem')
|
|
25
|
+
process.exitCode = 1
|
|
26
|
+
return
|
|
27
27
|
}
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
console.
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
console.error(`
|
|
38
|
-
process.
|
|
28
|
+
try {
|
|
29
|
+
const [{ inspectMem }, bytes] = await Promise.all([
|
|
30
|
+
import('../index.js'),
|
|
31
|
+
fs.promises.readFile(path.resolve(file))
|
|
32
|
+
])
|
|
33
|
+
const result = await inspectMem(bytes)
|
|
34
|
+
console.info(JSON.stringify(result, null, 2))
|
|
35
|
+
if (result.status !== 'valid') process.exitCode = 2
|
|
36
|
+
} catch (error) {
|
|
37
|
+
console.error(`Unable to inspect ${file}: ${error instanceof Error ? error.message : String(error)}`)
|
|
38
|
+
process.exitCode = 1
|
|
39
39
|
}
|
|
40
|
-
|
|
41
|
-
console.log(`Editor detected: ${found}. Installing memorio extension...`);
|
|
42
|
-
const result = spawnSync(found, ['--install-extension', vsixPath], {
|
|
43
|
-
stdio: 'inherit',
|
|
44
|
-
shell: os.platform() === 'win32',
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
if (result.status !== 0) {
|
|
48
|
-
console.error('Installation failed. Try manually:');
|
|
49
|
-
console.error(` ${found} --install-extension "${vsixPath}"`);
|
|
50
|
-
process.exit(result.status || 1);
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
console.log('Memorio extension installed successfully.');
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
function candidateBinaries() {
|
|
57
|
-
const names = ['codium', 'vscodium', 'code', 'code-insiders'];
|
|
58
|
-
if (os.platform() === 'win32') {
|
|
59
|
-
return names.map((n) => `${n}.cmd`);
|
|
60
|
-
}
|
|
61
|
-
return names;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
function isAvailable(bin) {
|
|
65
|
-
const checkCmd = os.platform() === 'win32' ? 'where' : 'which';
|
|
66
|
-
const result = spawnSync(checkCmd, [bin], { stdio: 'ignore', shell: true });
|
|
67
|
-
return result.status === 0;
|
|
68
40
|
}
|
|
41
|
+
|
|
42
|
+
function installExtension() {
|
|
43
|
+
const vsixPath = path.join(__dirname, '..', 'vsix', 'memorio.vsix')
|
|
44
|
+
|
|
45
|
+
if (!fs.existsSync(vsixPath)) {
|
|
46
|
+
console.error(`VSIX file not found at ${vsixPath}.`)
|
|
47
|
+
console.error('The npm package may be corrupted, or the build did not copy the .vsix into vsix/.')
|
|
48
|
+
process.exit(1)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const candidates = candidateBinaries()
|
|
52
|
+
const found = candidates.find((bin) => isAvailable(bin))
|
|
53
|
+
|
|
54
|
+
if (!found) {
|
|
55
|
+
console.error('No compatible editor found in PATH (tried: ' + candidates.join(', ') + ').')
|
|
56
|
+
console.error('Manual installation:')
|
|
57
|
+
console.error(' 1. Open your editor (VSCodium/VSCode)')
|
|
58
|
+
console.error(' 2. Command Palette -> "Extensions: Install from VSIX..."')
|
|
59
|
+
console.error(` 3. Select: ${vsixPath}`)
|
|
60
|
+
process.exit(1)
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
console.info(`Editor detected: ${found}. Installing memorio extension...`)
|
|
64
|
+
const result = spawnSync(found, ['--install-extension', vsixPath], {
|
|
65
|
+
stdio: 'inherit',
|
|
66
|
+
shell: os.platform() === 'win32',
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
if (result.status !== 0) {
|
|
70
|
+
console.error('Installation failed. Try manually:')
|
|
71
|
+
console.error(` ${found} --install-extension "${vsixPath}"`)
|
|
72
|
+
process.exit(result.status || 1)
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
console.info('Memorio extension installed successfully.')
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function candidateBinaries() {
|
|
79
|
+
const names = ['codium', 'vscodium', 'code', 'code-insiders']
|
|
80
|
+
if (os.platform() === 'win32') {
|
|
81
|
+
return names.map((n) => `${n}.cmd`)
|
|
82
|
+
}
|
|
83
|
+
return names
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function isAvailable(bin) {
|
|
87
|
+
const checkCmd = os.platform() === 'win32' ? 'where' : 'which'
|
|
88
|
+
const result = spawnSync(checkCmd, [bin], { stdio: 'ignore', shell: true })
|
|
89
|
+
return result.status === 0
|
|
90
|
+
}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* acquired-knowledge.ts
|
|
3
|
+
*
|
|
4
|
+
* Scenario: an AI agent working on a real project needs to record lessons it
|
|
5
|
+
* learns during development so that future sessions can recall them instead
|
|
6
|
+
* of re-discovering the same issues.
|
|
7
|
+
*
|
|
8
|
+
* The complete workflow preserves an experience with `acquire()`, finds
|
|
9
|
+
* plausible prior experience from ordinary situation text with `discover()`,
|
|
10
|
+
* and prepares bounded untrusted context for an AI with `project()`.
|
|
11
|
+
* `context({ acquired })` remains the separate exact applicability selector.
|
|
12
|
+
*
|
|
13
|
+
* Run: npx tsx docs/examples/acquired-knowledge.ts
|
|
14
|
+
*/
|
|
15
|
+
import { memorio } from 'memorio'
|
|
16
|
+
|
|
17
|
+
const mem = memorio.memory
|
|
18
|
+
|
|
19
|
+
async function main() {
|
|
20
|
+
// ============================================
|
|
21
|
+
// 1. Check exact current state before acquiring this fixed demo identity.
|
|
22
|
+
// This keeps the example safe to run again without duplicating claim IDs.
|
|
23
|
+
// ============================================
|
|
24
|
+
|
|
25
|
+
console.debug('=== Checking for Existing Knowledge ===\n')
|
|
26
|
+
|
|
27
|
+
const existing = await mem.context({
|
|
28
|
+
acquired: { area: 'css', component: 'layout', pattern: 'grid-min-content' }
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
if (existing.claims.length > 0) {
|
|
32
|
+
console.debug(`Found ${existing.claims.length} relevant claim(s):`)
|
|
33
|
+
for (const claim of existing.claims) {
|
|
34
|
+
console.debug(` - [${claim.id}]`, JSON.stringify(claim.knowledge))
|
|
35
|
+
console.debug(` Evidence:`, claim.evidence)
|
|
36
|
+
if (claim.revision) {
|
|
37
|
+
console.debug(` Revision:`, claim.revision)
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
console.debug('')
|
|
41
|
+
} else {
|
|
42
|
+
console.debug('No prior knowledge found for this context. Proceeding fresh.\n')
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// ============================================
|
|
46
|
+
// 2. Acquire knowledge after learning it
|
|
47
|
+
// ============================================
|
|
48
|
+
|
|
49
|
+
console.debug('=== Acquiring Knowledge When Missing ===\n')
|
|
50
|
+
|
|
51
|
+
// Lesson learned: a CSS grid track sized with min-content also incorporates
|
|
52
|
+
// the inner element's margins. Replacing it with a fixed width changes the
|
|
53
|
+
// effective rendered track.
|
|
54
|
+
if (existing.claims.length === 0) await mem.acquire({
|
|
55
|
+
id: 'css.grid.min-content-margins',
|
|
56
|
+
knowledge: {
|
|
57
|
+
guidance: 'Replacing a min-content grid track with the inner element fixed width changes the effective rendered track width because min-content sizing incorporates the inner element margins.',
|
|
58
|
+
impact: 'Layout shifted when a fixed-width aside replaced a min-content grid track.'
|
|
59
|
+
},
|
|
60
|
+
applies: { area: 'css', component: 'layout', pattern: 'grid-min-content' },
|
|
61
|
+
evidence: [{
|
|
62
|
+
id: 'layout-debug-20260918',
|
|
63
|
+
source: 'real-project',
|
|
64
|
+
observedAt: '2026-09-18T12:30:00Z'
|
|
65
|
+
}],
|
|
66
|
+
epistemicType: 'observed',
|
|
67
|
+
provenance: { source: 'example-project', detail: 'Observed during layout debugging.' }
|
|
68
|
+
})
|
|
69
|
+
console.debug(existing.claims.length === 0
|
|
70
|
+
? 'Acquired: css.grid.min-content-margins\n'
|
|
71
|
+
: 'The demo already has active general knowledge; acquisition skipped.\n')
|
|
72
|
+
|
|
73
|
+
// ============================================
|
|
74
|
+
// 3. Discover from ordinary situation text, then project for AI transfer
|
|
75
|
+
// ============================================
|
|
76
|
+
|
|
77
|
+
console.debug('=== Discovering and Projecting Prior Experience ===\n')
|
|
78
|
+
|
|
79
|
+
const found = await mem.discover(
|
|
80
|
+
'An aside layout shifted after changing CSS grid track sizing and margins.'
|
|
81
|
+
)
|
|
82
|
+
const projected = mem.project(found, { maxCandidates: 3, maxCharacters: 4_000 })
|
|
83
|
+
|
|
84
|
+
console.debug('Discovered candidates:', found.candidates.map(candidate => candidate.claim.id))
|
|
85
|
+
console.debug('Projected candidates:', projected.experiences.map(experience => experience.id))
|
|
86
|
+
console.debug('Omitted candidates:', projected.omittedCandidates)
|
|
87
|
+
console.debug('AI context (prior experience, not current truth):\n', projected.text)
|
|
88
|
+
console.debug('Verify projected experience against the current project before acting.\n')
|
|
89
|
+
|
|
90
|
+
// ============================================
|
|
91
|
+
// 4. Use exact applicability selection when the context is known
|
|
92
|
+
// ============================================
|
|
93
|
+
|
|
94
|
+
console.debug('=== Selecting Exact Acquired Context ===\n')
|
|
95
|
+
|
|
96
|
+
const context = await mem.context({
|
|
97
|
+
acquired: { area: 'css', component: 'layout', pattern: 'grid-min-content' }
|
|
98
|
+
})
|
|
99
|
+
|
|
100
|
+
console.debug('Knowledge version:', context.knowledgeVersion)
|
|
101
|
+
for (const claim of context.claims) {
|
|
102
|
+
console.debug(`Claim: ${claim.id}`)
|
|
103
|
+
console.debug(' Knowledge:', JSON.stringify(claim.knowledge))
|
|
104
|
+
console.debug(' Applies:', JSON.stringify(claim.applicability))
|
|
105
|
+
console.debug(' Evidence:', JSON.stringify(claim.evidence))
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// ============================================
|
|
109
|
+
// 5. Refine with more specific knowledge
|
|
110
|
+
// ============================================
|
|
111
|
+
|
|
112
|
+
console.debug('\n=== Refining with More Specific Knowledge ===\n')
|
|
113
|
+
|
|
114
|
+
let specific = await mem.context({
|
|
115
|
+
acquired: { area: 'css', component: 'layout', pattern: 'grid-min-content', element: 'aside' }
|
|
116
|
+
})
|
|
117
|
+
const hasSpecificDemo = specific.claims.some(claim => claim.id === 'css.grid.aside-min-content')
|
|
118
|
+
if (!hasSpecificDemo) await mem.acquire({
|
|
119
|
+
id: 'css.grid.aside-min-content',
|
|
120
|
+
knowledge: {
|
|
121
|
+
guidance: 'For aside elements in a grid with min-content tracks, retain min-content and set max-width on the inner content instead of replacing the track sizing.',
|
|
122
|
+
},
|
|
123
|
+
applies: { area: 'css', component: 'layout', pattern: 'grid-min-content', element: 'aside' },
|
|
124
|
+
evidence: [{ id: 'layout-debug-20260918' }],
|
|
125
|
+
refines: 'css.grid.min-content-margins'
|
|
126
|
+
})
|
|
127
|
+
if (!hasSpecificDemo) {
|
|
128
|
+
console.debug('Acquired refinement: css.grid.aside-min-content\n')
|
|
129
|
+
specific = await mem.context({
|
|
130
|
+
acquired: { area: 'css', component: 'layout', pattern: 'grid-min-content', element: 'aside' }
|
|
131
|
+
})
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// Query the specific context - gets only the more specific claim
|
|
135
|
+
console.debug('Specific context claims:', specific.claims.map(c => c.id))
|
|
136
|
+
|
|
137
|
+
// Query the general context - gets only the general claim
|
|
138
|
+
const general = await mem.context({
|
|
139
|
+
acquired: { area: 'css', component: 'layout', pattern: 'grid-min-content' }
|
|
140
|
+
})
|
|
141
|
+
console.debug('General context claims:', general.claims.map(c => c.id))
|
|
142
|
+
|
|
143
|
+
// ============================================
|
|
144
|
+
// 6. Supersede outdated knowledge
|
|
145
|
+
// ============================================
|
|
146
|
+
|
|
147
|
+
console.debug('\n=== Superseding Outdated Knowledge ===\n')
|
|
148
|
+
|
|
149
|
+
if (!general.claims.some(claim => claim.id === 'css.grid.min-content-margins.v2')) await mem.acquire({
|
|
150
|
+
id: 'css.grid.min-content-margins.v2',
|
|
151
|
+
knowledge: {
|
|
152
|
+
guidance: 'Prefer explicit track sizing (fr units) over min-content for predictable layouts. Min-content still incorporates margins; use this understanding when explicit control is needed.',
|
|
153
|
+
},
|
|
154
|
+
applies: { area: 'css', component: 'layout', pattern: 'grid-min-content' },
|
|
155
|
+
evidence: [{ id: 'layout-debug-20260918' }],
|
|
156
|
+
supersedes: 'css.grid.min-content-margins'
|
|
157
|
+
})
|
|
158
|
+
console.debug(general.claims.some(claim => claim.id === 'css.grid.min-content-margins.v2')
|
|
159
|
+
? 'The demo replacement is already current; supersede skipped.\n'
|
|
160
|
+
: 'Superseded old claim with v2.\n')
|
|
161
|
+
|
|
162
|
+
const afterSupersede = await mem.context({
|
|
163
|
+
acquired: { area: 'css', component: 'layout', pattern: 'grid-min-content' }
|
|
164
|
+
})
|
|
165
|
+
console.debug('After supersede, claims:', afterSupersede.claims.map(c => c.id))
|
|
166
|
+
|
|
167
|
+
// Acquired knowledge is intentionally persistent. Do not call clear() as
|
|
168
|
+
// routine cleanup: in a real project it would erase unrelated memory too.
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
main().catch(err => {
|
|
172
|
+
console.error('ERROR:', err)
|
|
173
|
+
process.exit(1)
|
|
174
|
+
})
|