@elvisw/dsh-magic-context 0.0.0-bootstrap.0 → 0.0.0-stage
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/README.md +2 -452
- package/package.json +4 -108
- package/LICENSE +0 -23
- package/NOTICE +0 -93
- package/README.zh-CN.md +0 -368
- package/cordis.patch.yml +0 -20
- package/lib/client.js +0 -2270
- package/lib/core/compartments.js +0 -424
- package/lib/core/corpus-store.js +0 -176
- package/lib/core/directive-detect.js +0 -147
- package/lib/core/domain-reconcile.js +0 -394
- package/lib/core/domains.js +0 -127
- package/lib/core/embedding-local.js +0 -247
- package/lib/core/global-autostage.js +0 -223
- package/lib/core/global-domains.js +0 -302
- package/lib/core/journal.js +0 -248
- package/lib/core/llm-deadline.js +0 -53
- package/lib/core/machine-domain.js +0 -106
- package/lib/core/maintenance.js +0 -380
- package/lib/core/memory-bridge.js +0 -818
- package/lib/core/memory-categories.js +0 -84
- package/lib/core/memory-scoring.js +0 -65
- package/lib/core/memory-search.js +0 -414
- package/lib/core/memory-write.js +0 -1176
- package/lib/core/policy.js +0 -111
- package/lib/core/profile-confirmation.js +0 -55
- package/lib/core/profile-review.js +0 -375
- package/lib/core/profile-write.js +0 -283
- package/lib/core/reference-seeds.js +0 -63
- package/lib/core/route-health.js +0 -106
- package/lib/core/stores.js +0 -1021
- package/lib/core/tagger.js +0 -7
- package/lib/core/types.js +0 -15
- package/lib/core/vector-backfill.js +0 -140
- package/lib/core/vector-lane.js +0 -184
- package/lib/dsh/command-surface.js +0 -376
- package/lib/dsh/compaction-engine.js +0 -231
- package/lib/dsh/config-switches.js +0 -56
- package/lib/dsh/config.js +0 -13
- package/lib/dsh/context-pressure.js +0 -36
- package/lib/dsh/drop-landing.js +0 -42
- package/lib/dsh/emergency.js +0 -89
- package/lib/dsh/flush-command.js +0 -148
- package/lib/dsh/global-review.js +0 -412
- package/lib/dsh/historian.js +0 -907
- package/lib/dsh/live-journal.js +0 -81
- package/lib/dsh/maintenance-wiring.js +0 -229
- package/lib/dsh/management-pass.js +0 -564
- package/lib/dsh/memory-lane.js +0 -535
- package/lib/dsh/pre-step.js +0 -675
- package/lib/dsh/project-drift.js +0 -116
- package/lib/dsh/recomp.js +0 -192
- package/lib/dsh/reduce-guidance.js +0 -188
- package/lib/dsh/seams.js +0 -588
- package/lib/dsh/search-hint.js +0 -186
- package/lib/dsh/session-notice.js +0 -100
- package/lib/dsh/status-command.js +0 -75
- package/lib/dsh/telemetry.js +0 -349
- package/lib/dsh/tool-bridge.js +0 -1009
- package/lib/dsh/volatile.js +0 -89
- package/lib/index.js +0 -931
- package/tools/migrate-profile-package-name.mjs +0 -317
- package/vendor/onnx/LICENSE +0 -27
- package/vendor/onnx/ort-wasm-simd-threaded.mjs +0 -59
- package/vendor/onnx/ort-wasm-simd-threaded.wasm +0 -0
- package/vendor/onnx/ort.node.min.mjs +0 -8
|
@@ -1,376 +0,0 @@
|
|
|
1
|
-
import { decideConfirmation, listPendingConfirmations } from "../core/profile-confirmation.js";
|
|
2
|
-
import { ORG_DOMAIN_ID, approvalGate, detectGlobalCandidates, promoteMemoryToCandidate, publishGlobalCandidate, } from "../core/global-domains.js";
|
|
3
|
-
import { DEFAULT_DOMAIN_BUDGET_TOKENS, DEFAULT_SHARE_CATEGORIES, defaultDomainCap, isDomainKind, } from "../core/domains.js";
|
|
4
|
-
const PROFILE_USAGE = 'list | show <id> | confirm <id> | reject <id> | retire <id> --yes';
|
|
5
|
-
const GLOBAL_USAGE = 'domains | create <domain> --kind org|machine | members [<domain>] | enable <domain> | disable <domain> --yes | '
|
|
6
|
-
+ 'add <domain> <identity> | remove <domain> <identity> --yes | candidates [<domain>] | '
|
|
7
|
-
+ 'promote <memoryId> [--domain <domain>] | detect | approve <candidateId> --yes | reject-candidate <candidateId> --yes | '
|
|
8
|
-
+ 'review via ctx_memory action=review_global (approval cards)';
|
|
9
|
-
/** Flag value extractor: `--kind org` → 'org'. */
|
|
10
|
-
function flagValue(tokens, name) {
|
|
11
|
-
const index = tokens.indexOf(name);
|
|
12
|
-
return index === -1 || index + 1 >= tokens.length ? undefined : tokens[index + 1];
|
|
13
|
-
}
|
|
14
|
-
function tokenize(rawInput) {
|
|
15
|
-
return (rawInput ?? '').trim().split(/\s+/).filter(token => token.length > 0);
|
|
16
|
-
}
|
|
17
|
-
function wantsApply(tokens) {
|
|
18
|
-
return tokens.includes('--yes') || tokens.includes('-y');
|
|
19
|
-
}
|
|
20
|
-
function stripFlags(tokens) {
|
|
21
|
-
return tokens.filter(token => !token.startsWith('-'));
|
|
22
|
-
}
|
|
23
|
-
function parseId(raw) {
|
|
24
|
-
if (raw === undefined)
|
|
25
|
-
return undefined;
|
|
26
|
-
const value = Number(raw);
|
|
27
|
-
return Number.isInteger(value) && value > 0 ? value : undefined;
|
|
28
|
-
}
|
|
29
|
-
// ── /ctx-profile ───────────────────────────────────────────────────────────
|
|
30
|
-
/**
|
|
31
|
-
* Plan or perform one `/ctx-profile` invocation.
|
|
32
|
-
*
|
|
33
|
-
* `confirm` is intentionally NOT gated behind `--yes`: it is the action the
|
|
34
|
-
* notice asks the human to take, and gating it would make the queue harder to
|
|
35
|
-
* drain than to fill. `reject` IS gated, because a rejection is what makes a
|
|
36
|
-
* candidate disappear from the reviewer's view for good.
|
|
37
|
-
*/
|
|
38
|
-
export function planProfileCommand(store, rawInput, now, profileWriter) {
|
|
39
|
-
const tokens = stripFlags(tokenize(rawInput));
|
|
40
|
-
const verb = tokens[0] ?? 'list';
|
|
41
|
-
if (verb === 'list') {
|
|
42
|
-
const pending = listPendingConfirmations(store);
|
|
43
|
-
if (pending.length === 0)
|
|
44
|
-
return { kind: 'success', text: 'Magic Context: no profile candidate is waiting.' };
|
|
45
|
-
const blocks = pending.map(row => `#${String(row.id)}\n${row.question}`);
|
|
46
|
-
return {
|
|
47
|
-
kind: 'success',
|
|
48
|
-
text: [`${String(pending.length)} candidate(s) waiting:`, ...blocks, `Reply with: /ctx-profile ${PROFILE_USAGE}`].join('\n\n'),
|
|
49
|
-
};
|
|
50
|
-
}
|
|
51
|
-
if (verb === 'show') {
|
|
52
|
-
const id = parseId(tokens[1]);
|
|
53
|
-
const row = id === undefined
|
|
54
|
-
? undefined
|
|
55
|
-
: store.listProfileConfirmations().find(candidate => candidate.id === id);
|
|
56
|
-
if (row === undefined)
|
|
57
|
-
return { kind: 'error', text: `Magic Context: no confirmation #${tokens[1] ?? '?'}.` };
|
|
58
|
-
return { kind: 'success', text: `#${String(row.id)} [${row.state}]\n${row.question}` };
|
|
59
|
-
}
|
|
60
|
-
if (verb === 'confirm') {
|
|
61
|
-
const id = parseId(tokens[1]);
|
|
62
|
-
if (id === undefined)
|
|
63
|
-
return { kind: 'error', text: `Magic Context: /ctx-profile confirm needs an id. Usage: ${PROFILE_USAGE}` };
|
|
64
|
-
const decided = decideConfirmation(store, id, 'approved', now);
|
|
65
|
-
if (decided === undefined)
|
|
66
|
-
return { kind: 'error', text: `Magic Context: #${String(id)} is not waiting for a decision.` };
|
|
67
|
-
return {
|
|
68
|
-
kind: 'success',
|
|
69
|
-
text: `Magic Context: #${String(id)} confirmed. It is now an approved profile rule and takes effect in every session.\n`
|
|
70
|
-
+ 'Promotion into the shared profile happens on the next maintenance tick; nothing is written from this command.',
|
|
71
|
-
};
|
|
72
|
-
}
|
|
73
|
-
if (verb === 'reject') {
|
|
74
|
-
const id = parseId(tokens[1]);
|
|
75
|
-
if (id === undefined)
|
|
76
|
-
return { kind: 'error', text: `Magic Context: /ctx-profile reject needs an id. Usage: ${PROFILE_USAGE}` };
|
|
77
|
-
if (!wantsApply(tokenize(rawInput))) {
|
|
78
|
-
return { kind: 'success', text: `Magic Context: would reject #${String(id)} (add --yes to apply).` };
|
|
79
|
-
}
|
|
80
|
-
const decided = decideConfirmation(store, id, 'rejected', now);
|
|
81
|
-
if (decided === undefined)
|
|
82
|
-
return { kind: 'error', text: `Magic Context: #${String(id)} is not waiting for a decision.` };
|
|
83
|
-
return { kind: 'success', text: `Magic Context: #${String(id)} rejected. It will never be promoted.` };
|
|
84
|
-
}
|
|
85
|
-
if (verb === 'retire') {
|
|
86
|
-
const id = parseId(tokens[1]);
|
|
87
|
-
if (id === undefined)
|
|
88
|
-
return { kind: 'error', text: `Magic Context: /ctx-profile retire needs a profile id. Usage: ${PROFILE_USAGE}` };
|
|
89
|
-
if (profileWriter === undefined || profileWriter.status.ok !== true) {
|
|
90
|
-
return {
|
|
91
|
-
kind: 'error',
|
|
92
|
-
text: 'Magic Context: the shared profile is not writable right now, so the row was left as it is.',
|
|
93
|
-
};
|
|
94
|
-
}
|
|
95
|
-
const row = profileWriter.listActiveProfiles().find(profile => profile.id === id);
|
|
96
|
-
if (row === undefined) {
|
|
97
|
-
// Distinguishing "not active" from "not writable" matters: an id that is
|
|
98
|
-
// already dismissed must not look like a failed write.
|
|
99
|
-
return { kind: 'error', text: `Magic Context: #${String(id)} is not an active profile row.` };
|
|
100
|
-
}
|
|
101
|
-
if (!wantsApply(tokenize(rawInput))) {
|
|
102
|
-
return {
|
|
103
|
-
kind: 'success',
|
|
104
|
-
text: `Magic Context: would retire #${String(id)} — "${row.content.slice(0, 120)}".\n`
|
|
105
|
-
+ 'It would stop being injected in every session, and the removal forces a HARD baseline rebuild '
|
|
106
|
-
+ '(the profile digest covers active rows). Add --yes to apply.',
|
|
107
|
-
};
|
|
108
|
-
}
|
|
109
|
-
if (!profileWriter.retireProfile(id, now)) {
|
|
110
|
-
return { kind: 'error', text: `Magic Context: #${String(id)} could not be retired; nothing changed.` };
|
|
111
|
-
}
|
|
112
|
-
return {
|
|
113
|
-
kind: 'success',
|
|
114
|
-
text: `Magic Context: #${String(id)} retired. It no longer renders in <user-profile>, and every session `
|
|
115
|
-
+ 'that had it folds its baseline on the next pass (the digest covers active rows). The row itself is '
|
|
116
|
-
+ 'kept as dismissed — it is the record of what was once injected.',
|
|
117
|
-
};
|
|
118
|
-
}
|
|
119
|
-
return { kind: 'error', text: `Magic Context: unknown /ctx-profile subcommand '${verb}'. Usage: ${PROFILE_USAGE}` };
|
|
120
|
-
}
|
|
121
|
-
// ── /ctx-global ────────────────────────────────────────────────────────────
|
|
122
|
-
/** Display label for a domain kind (2026-10-25 naming: the axis is AUDIENCE — machine=全局, org=工作). */
|
|
123
|
-
function kindLabel(kind) {
|
|
124
|
-
if (kind === 'machine')
|
|
125
|
-
return '全局';
|
|
126
|
-
if (kind === 'org')
|
|
127
|
-
return '工作';
|
|
128
|
-
if (kind === 'user')
|
|
129
|
-
return '画像';
|
|
130
|
-
return kind;
|
|
131
|
-
}
|
|
132
|
-
function domainLine(store, domain) {
|
|
133
|
-
const members = store.listDomainMembers(domain.domainId).length;
|
|
134
|
-
return `- ${domain.domainId} [${domain.kind}·${kindLabel(domain.kind)}] ${domain.enabled ? 'enabled' : 'disabled'}`
|
|
135
|
-
+ ` · budget ${String(domain.budgetTokens)} tok · cap ${String(domain.cap)}`
|
|
136
|
-
+ ` · shares ${domain.shareCategories.length === 0 ? '(nothing)' : domain.shareCategories.join(', ')}`
|
|
137
|
-
+ ` · ${String(members)} member(s)`;
|
|
138
|
-
}
|
|
139
|
-
export function planGlobalCommand(store, rawInput, now, corpusDbPath, publisher) {
|
|
140
|
-
// Flags must be read from the RAW tokens: stripFlags removes every
|
|
141
|
-
// `-`-prefixed token, so any flag looked up in `tokens` is invisible (the
|
|
142
|
-
// 2026-10-12 promote --domain bug: the flag was always "absent", so every
|
|
143
|
-
// promotion silently landed in org — even one naming an unknown domain).
|
|
144
|
-
const rawTokens = tokenize(rawInput);
|
|
145
|
-
const tokens = stripFlags(rawTokens);
|
|
146
|
-
const verb = tokens[0] ?? 'domains';
|
|
147
|
-
if (verb === 'domains') {
|
|
148
|
-
const domains = store.listDomains();
|
|
149
|
-
if (domains.length === 0) {
|
|
150
|
-
return {
|
|
151
|
-
kind: 'success',
|
|
152
|
-
text: 'Magic Context: no global domain is defined yet. '
|
|
153
|
-
+ 'Create one with: /ctx-global create <domain-id> --kind org|machine '
|
|
154
|
-
+ '(e.g. /ctx-global create dir:global:org --kind org), then add members with: /ctx-global add <domain-id> <identity>',
|
|
155
|
-
};
|
|
156
|
-
}
|
|
157
|
-
return { kind: 'success', text: ['Global domains:', ...domains.map(domain => domainLine(store, domain))].join('\n') };
|
|
158
|
-
}
|
|
159
|
-
if (verb === 'create') {
|
|
160
|
-
const rawTokens = tokenize(rawInput);
|
|
161
|
-
const domainId = tokens[1];
|
|
162
|
-
const kind = flagValue(rawTokens, '--kind') ?? 'org';
|
|
163
|
-
if (domainId === undefined) {
|
|
164
|
-
return { kind: 'error', text: `Magic Context: /ctx-global create needs <domain>. Usage: ${GLOBAL_USAGE}` };
|
|
165
|
-
}
|
|
166
|
-
if (!isDomainKind(kind)) {
|
|
167
|
-
return { kind: 'error', text: `Magic Context: --kind must be org (工作域, curated work projects) or machine (全局域, every project on this machine) — got '${kind}'. Usage: ${GLOBAL_USAGE}` };
|
|
168
|
-
}
|
|
169
|
-
if (store.getDomain(domainId) !== undefined) {
|
|
170
|
-
return { kind: 'error', text: `Magic Context: domain '${domainId}' already exists.` };
|
|
171
|
-
}
|
|
172
|
-
// Born with the derived defaults, exactly like the machine bootstrap
|
|
173
|
-
// (machine-domain.ts) — the operator can edit budget/cap/allowlist later.
|
|
174
|
-
store.upsertDomain({
|
|
175
|
-
domainId,
|
|
176
|
-
kind,
|
|
177
|
-
enabled: true,
|
|
178
|
-
budgetTokens: DEFAULT_DOMAIN_BUDGET_TOKENS[kind],
|
|
179
|
-
cap: defaultDomainCap(kind),
|
|
180
|
-
shareCategories: [...DEFAULT_SHARE_CATEGORIES],
|
|
181
|
-
}, now);
|
|
182
|
-
return { kind: 'success', text: `Magic Context: domain ${domainId} (kind ${kind}) created and enabled. Add members with: /ctx-global add ${domainId} <identity>` };
|
|
183
|
-
}
|
|
184
|
-
if (verb === 'members') {
|
|
185
|
-
const domainId = tokens[1];
|
|
186
|
-
const rows = store.listDomainMembers(domainId);
|
|
187
|
-
if (rows.length === 0) {
|
|
188
|
-
return { kind: 'success', text: domainId === undefined ? 'Magic Context: no domain members.' : `Magic Context: ${domainId} has no members (it activates nothing).` };
|
|
189
|
-
}
|
|
190
|
-
return { kind: 'success', text: rows.map(row => `- ${row.identity} (${row.domainId})`).join('\n') };
|
|
191
|
-
}
|
|
192
|
-
if (verb === 'add') {
|
|
193
|
-
const domainId = tokens[1];
|
|
194
|
-
const identity = tokens[2];
|
|
195
|
-
if (domainId === undefined || identity === undefined) {
|
|
196
|
-
return { kind: 'error', text: `Magic Context: /ctx-global add needs <domain> <identity>. Usage: ${GLOBAL_USAGE}` };
|
|
197
|
-
}
|
|
198
|
-
if (store.getDomain(domainId) === undefined) {
|
|
199
|
-
return { kind: 'error', text: `Magic Context: unknown domain '${domainId}'.` };
|
|
200
|
-
}
|
|
201
|
-
store.addDomainMember(domainId, identity, now);
|
|
202
|
-
return { kind: 'success', text: `Magic Context: ${identity} now activates ${domainId}.` };
|
|
203
|
-
}
|
|
204
|
-
if (verb === 'remove') {
|
|
205
|
-
const domainId = tokens[1];
|
|
206
|
-
const identity = tokens[2];
|
|
207
|
-
if (domainId === undefined || identity === undefined) {
|
|
208
|
-
return { kind: 'error', text: `Magic Context: /ctx-global remove needs <domain> <identity>. Usage: ${GLOBAL_USAGE}` };
|
|
209
|
-
}
|
|
210
|
-
if (!wantsApply(tokenize(rawInput))) {
|
|
211
|
-
return { kind: 'success', text: `Magic Context: would remove ${identity} from ${domainId} (add --yes to apply).` };
|
|
212
|
-
}
|
|
213
|
-
store.removeDomainMember(domainId, identity);
|
|
214
|
-
return { kind: 'success', text: `Magic Context: ${identity} no longer activates ${domainId}.` };
|
|
215
|
-
}
|
|
216
|
-
if (verb === 'enable' || verb === 'disable') {
|
|
217
|
-
const domainId = tokens[1];
|
|
218
|
-
if (domainId === undefined) {
|
|
219
|
-
return { kind: 'error', text: `Magic Context: /ctx-global ${verb} needs a domain. Usage: ${GLOBAL_USAGE}` };
|
|
220
|
-
}
|
|
221
|
-
const enabled = verb === 'enable';
|
|
222
|
-
if (!enabled && !wantsApply(tokenize(rawInput))) {
|
|
223
|
-
return { kind: 'success', text: `Magic Context: would disable ${domainId} (add --yes to apply).` };
|
|
224
|
-
}
|
|
225
|
-
if (store.getDomain(domainId) === undefined) {
|
|
226
|
-
return { kind: 'error', text: `Magic Context: unknown domain '${domainId}'.` };
|
|
227
|
-
}
|
|
228
|
-
store.setDomainEnabled(domainId, enabled, now);
|
|
229
|
-
return {
|
|
230
|
-
kind: 'success',
|
|
231
|
-
text: enabled
|
|
232
|
-
? `Magic Context: ${domainId} enabled. Its rows become visible to its members on the next pass.`
|
|
233
|
-
: `Magic Context: ${domainId} disabled. Its rows stop being injected; existing memories stay in the shared store.`,
|
|
234
|
-
};
|
|
235
|
-
}
|
|
236
|
-
if (verb === 'detect') {
|
|
237
|
-
if (corpusDbPath === undefined) {
|
|
238
|
-
return { kind: 'error', text: 'Magic Context: the shared store is unavailable, so recurrence cannot be scanned.' };
|
|
239
|
-
}
|
|
240
|
-
const scan = detectGlobalCandidates(store, { corpusDbPath, now });
|
|
241
|
-
if (scan.hashes === 0) {
|
|
242
|
-
return {
|
|
243
|
-
kind: 'success',
|
|
244
|
-
text: 'Magic Context: recurrence scan found 0 cross-project candidates.\n'
|
|
245
|
-
+ 'That is the expected result on this corpus (measured 2026-10-10: 1292 active rows across 33 projects, '
|
|
246
|
-
+ 'no normalized hash shared by two projects) — historian facts are project-bound. '
|
|
247
|
-
+ 'Use /ctx-global promote <memoryId> for human-judged work-domain knowledge.',
|
|
248
|
-
};
|
|
249
|
-
}
|
|
250
|
-
return {
|
|
251
|
-
kind: 'success',
|
|
252
|
-
text: `Magic Context: recurrence scan found ${String(scan.hashes)} hash(es); upserted ${String(scan.upserted)}, `
|
|
253
|
-
+ `skipped ${String(scan.blocked)} credential-shaped.`,
|
|
254
|
-
};
|
|
255
|
-
}
|
|
256
|
-
if (verb === 'promote') {
|
|
257
|
-
const memoryId = parseId(tokens[1]);
|
|
258
|
-
if (memoryId === undefined) {
|
|
259
|
-
return { kind: 'error', text: `Magic Context: /ctx-global promote needs a memory id. Usage: ${GLOBAL_USAGE}` };
|
|
260
|
-
}
|
|
261
|
-
if (corpusDbPath === undefined) {
|
|
262
|
-
return { kind: 'error', text: 'Magic Context: the shared store is unavailable, so a memory cannot be read.' };
|
|
263
|
-
}
|
|
264
|
-
const domainFlag = rawTokens.indexOf('--domain');
|
|
265
|
-
const domainValue = domainFlag >= 0 ? rawTokens[domainFlag + 1] : undefined;
|
|
266
|
-
// A flag without a value (or followed by another flag) must FAIL, not fall
|
|
267
|
-
// back to org: a silent fallback publishes human-judged knowledge to the
|
|
268
|
-
// wrong audience, which is the one mistake this flag exists to prevent.
|
|
269
|
-
if (domainFlag >= 0 && (domainValue === undefined || domainValue.startsWith('-'))) {
|
|
270
|
-
return { kind: 'error', text: `Magic Context: --domain needs a value. Usage: ${GLOBAL_USAGE}` };
|
|
271
|
-
}
|
|
272
|
-
const domainId = domainValue ?? ORG_DOMAIN_ID;
|
|
273
|
-
const promoted = promoteMemoryToCandidate(store, {
|
|
274
|
-
corpusDbPath,
|
|
275
|
-
memoryId,
|
|
276
|
-
domainId,
|
|
277
|
-
now,
|
|
278
|
-
});
|
|
279
|
-
if (!promoted.ok)
|
|
280
|
-
return { kind: 'error', text: `Magic Context: ${promoted.error}` };
|
|
281
|
-
const candidate = promoted.candidate;
|
|
282
|
-
return {
|
|
283
|
-
kind: 'success',
|
|
284
|
-
text: `Magic Context: memory #${String(memoryId)} is now candidate #${String(candidate.id)} for ${domainId}`
|
|
285
|
-
+ `${candidate.category === undefined ? '' : ` (category ${candidate.category})`}.\n`
|
|
286
|
-
+ `It is human-judged, so /ctx-global approve ${String(candidate.id)} does not need the recurrence gate.\n`
|
|
287
|
-
+ `Instant path next time: ctx_memory action=promote (memory_id + domain) enqueues AND raises the card.`,
|
|
288
|
-
};
|
|
289
|
-
}
|
|
290
|
-
if (verb === 'candidates') {
|
|
291
|
-
const domainId = tokens[1];
|
|
292
|
-
const rows = store.listGlobalCandidates({ state: 'pending', ...domainId === undefined ? {} : { domainId } });
|
|
293
|
-
if (rows.length === 0)
|
|
294
|
-
return { kind: 'success', text: 'Magic Context: no pending global candidate.' };
|
|
295
|
-
return {
|
|
296
|
-
kind: 'success',
|
|
297
|
-
text: rows.map(row => `- #${String(row.id)} [${row.domainId}] observed by ${String(row.distinctIdentities)} project(s), `
|
|
298
|
-
+ `${String(row.observationCount)} time(s): ${row.content.replace(/\s+/g, ' ').slice(0, 100)}`).join('\n'),
|
|
299
|
-
};
|
|
300
|
-
}
|
|
301
|
-
if (verb === 'approve' || verb === 'reject-candidate') {
|
|
302
|
-
const id = parseId(tokens[1]);
|
|
303
|
-
if (id === undefined) {
|
|
304
|
-
return { kind: 'error', text: `Magic Context: /ctx-global ${verb} needs a candidate id. Usage: ${GLOBAL_USAGE}` };
|
|
305
|
-
}
|
|
306
|
-
const apply = wantsApply(tokenize(rawInput));
|
|
307
|
-
const row = store.getGlobalCandidate(id);
|
|
308
|
-
if (row === undefined)
|
|
309
|
-
return { kind: 'error', text: `Magic Context: no candidate #${String(id)}.` };
|
|
310
|
-
if (verb === 'reject-candidate') {
|
|
311
|
-
if (!apply) {
|
|
312
|
-
return { kind: 'success', text: `Magic Context: would reject candidate #${String(id)} (add --yes to apply).` };
|
|
313
|
-
}
|
|
314
|
-
store.setGlobalCandidateState(id, 'rejected', now);
|
|
315
|
-
return { kind: 'success', text: `Magic Context: candidate #${String(id)} rejected.` };
|
|
316
|
-
}
|
|
317
|
-
// `approve` IS the publish: the state flag alone made a candidate that was
|
|
318
|
-
// "approved" and visible to nobody. The gate runs before the preview and
|
|
319
|
-
// before the apply, so the two can never disagree about publishability.
|
|
320
|
-
const gate = approvalGate(store, row, publisher);
|
|
321
|
-
if (!gate.ok)
|
|
322
|
-
return { kind: 'error', text: `Magic Context: ${gate.error}` };
|
|
323
|
-
if (!apply) {
|
|
324
|
-
return {
|
|
325
|
-
kind: 'success',
|
|
326
|
-
text: `Magic Context: would publish candidate #${String(id)} as ${row.domainId} [${row.category}] `
|
|
327
|
-
+ `— every peer project would see it. Add --yes to publish.`,
|
|
328
|
-
};
|
|
329
|
-
}
|
|
330
|
-
if (publisher === undefined) {
|
|
331
|
-
return {
|
|
332
|
-
kind: 'error',
|
|
333
|
-
text: 'Magic Context: the shared store is not writable right now (no memory writer), so the candidate '
|
|
334
|
-
+ 'was left pending rather than marked approved with nothing published.',
|
|
335
|
-
};
|
|
336
|
-
}
|
|
337
|
-
const published = publishGlobalCandidate(store, { candidateId: id, writer: publisher, now });
|
|
338
|
-
if (!published.ok)
|
|
339
|
-
return { kind: 'error', text: `Magic Context: ${published.error}` };
|
|
340
|
-
return {
|
|
341
|
-
kind: 'success',
|
|
342
|
-
text: `Magic Context: candidate #${String(id)} ${published.created ? 'published' : 'was already published'} `
|
|
343
|
-
+ `as memory #${String(published.memoryId)} under ${published.identity} [${published.category}]`
|
|
344
|
-
+ `${published.created ? '' : ' (its recurrence counter moved instead of a duplicate row)'}; `
|
|
345
|
-
+ 'every member project sees it now.',
|
|
346
|
-
};
|
|
347
|
-
}
|
|
348
|
-
return { kind: 'error', text: `Magic Context: unknown /ctx-global subcommand '${verb}'. Usage: ${GLOBAL_USAGE}` };
|
|
349
|
-
}
|
|
350
|
-
// ── registration ───────────────────────────────────────────────────────────
|
|
351
|
-
export function registerCtxProfileCommand(ctx, deps) {
|
|
352
|
-
const commands = ctx.get('commands');
|
|
353
|
-
if (commands === undefined) {
|
|
354
|
-
ctx.logger.warn('magic-context dsh adapter: commands service not mounted; /ctx-profile unavailable');
|
|
355
|
-
return;
|
|
356
|
-
}
|
|
357
|
-
commands.register({
|
|
358
|
-
name: 'ctx-profile',
|
|
359
|
-
description: 'Magic Context: answer the profile-confirmation queue (directive-shaped candidates need you).',
|
|
360
|
-
input: { hint: PROFILE_USAGE },
|
|
361
|
-
handler: invocation => planProfileCommand(deps.stores, invocation.rawInput, Date.now(), deps.profileWriter),
|
|
362
|
-
});
|
|
363
|
-
}
|
|
364
|
-
export function registerCtxGlobalCommand(ctx, deps) {
|
|
365
|
-
const commands = ctx.get('commands');
|
|
366
|
-
if (commands === undefined) {
|
|
367
|
-
ctx.logger.warn('magic-context dsh adapter: commands service not mounted; /ctx-global unavailable');
|
|
368
|
-
return;
|
|
369
|
-
}
|
|
370
|
-
commands.register({
|
|
371
|
-
name: 'ctx-global',
|
|
372
|
-
description: 'Magic Context: global domains — inspect, activate, and manage their membership.',
|
|
373
|
-
input: { hint: GLOBAL_USAGE },
|
|
374
|
-
handler: invocation => planGlobalCommand(deps.stores, invocation.rawInput, Date.now(), deps.corpusDbPath, deps.publisher),
|
|
375
|
-
});
|
|
376
|
-
}
|
|
@@ -1,231 +0,0 @@
|
|
|
1
|
-
import { randomUUID } from 'node:crypto';
|
|
2
|
-
import { compactedPlaceholder, estimateTokens } from "../core/compartments.js";
|
|
3
|
-
import { errText } from "../core/types.js";
|
|
4
|
-
import { callHistorian } from "./historian.js";
|
|
5
|
-
import { runManagementPass } from "./management-pass.js";
|
|
6
|
-
import { compactCheckpointSource, enumerateSurfaceNodes, replaceSurfaceRange, syntheticNodeId, } from "./seams.js";
|
|
7
|
-
function digestText(draft) {
|
|
8
|
-
const lines = [draft.tiers.p1];
|
|
9
|
-
if (draft.facts.length > 0) {
|
|
10
|
-
lines.push(`facts: ${draft.facts.map(fact => fact.category.length === 0 ? fact.content : `[${fact.category}] ${fact.content}`).join(' | ')}`);
|
|
11
|
-
}
|
|
12
|
-
if (draft.events.length > 0)
|
|
13
|
-
lines.push(`events: ${draft.events.join(' | ')}`);
|
|
14
|
-
return lines.join('\n');
|
|
15
|
-
}
|
|
16
|
-
/** Map an explicit surface span (first/last node seqs, either order) to nodes. */
|
|
17
|
-
function regionNodes(nodes, start, end) {
|
|
18
|
-
const first = nodes.findIndex(node => node.seq === start);
|
|
19
|
-
const last = nodes.findIndex(node => node.seq === end);
|
|
20
|
-
if (first === -1 || last === -1)
|
|
21
|
-
return [];
|
|
22
|
-
const [from, to] = first <= last ? [first, last] : [last, first];
|
|
23
|
-
return nodes.slice(from, to + 1);
|
|
24
|
-
}
|
|
25
|
-
/**
|
|
26
|
-
* Create and mount the adapter's CompactionEngine. Awaiting the returned
|
|
27
|
-
* promise settles once the service is provided (or rejects when another
|
|
28
|
-
* engine already owns `ctx.compaction`). The returned handle's `dispose()`
|
|
29
|
-
* unmounts the engine, so the caller can follow a runtime toggle off.
|
|
30
|
-
*/
|
|
31
|
-
export async function registerMagicCompactionEngine(ctx, deps) {
|
|
32
|
-
const base = deps.base;
|
|
33
|
-
/** The live policy at the use point (snapshot fallback: see deps). */
|
|
34
|
-
const policyNow = () => deps.activePolicy?.() ?? deps.policy;
|
|
35
|
-
/** The live generation route at the use point (snapshot fallback: see deps). */
|
|
36
|
-
const routeNow = () => {
|
|
37
|
-
const route = deps.activeRoute?.() ?? deps.route;
|
|
38
|
-
if (route === undefined)
|
|
39
|
-
return undefined;
|
|
40
|
-
const effort = deps.activeEffort?.()?.trim();
|
|
41
|
-
if (effort === undefined || effort === '' || route.reasoningEffort !== undefined)
|
|
42
|
-
return route;
|
|
43
|
-
return { ...route, reasoningEffort: effort };
|
|
44
|
-
};
|
|
45
|
-
const sessionOf = (agent) => {
|
|
46
|
-
const session = agent.session;
|
|
47
|
-
if (session === undefined)
|
|
48
|
-
throw new Error('compaction agent carries no session');
|
|
49
|
-
return session;
|
|
50
|
-
};
|
|
51
|
-
/** The manual checkpoint: summarize the span, then write the protocol. */
|
|
52
|
-
const writeCheckpoint = async (input) => {
|
|
53
|
-
if (deps.llm === undefined)
|
|
54
|
-
throw new Error('no LLM seam available for a manual compaction');
|
|
55
|
-
const sessionId = input.session.id;
|
|
56
|
-
const generationRoute = routeNow();
|
|
57
|
-
const systemSeq = enumerateSurfaceNodes(input.session).find(node => node.role === 'system')?.seq;
|
|
58
|
-
const draft = await callHistorian({
|
|
59
|
-
policy: policyNow(),
|
|
60
|
-
llm: deps.llm,
|
|
61
|
-
logger: deps.logger,
|
|
62
|
-
...deps.journal === undefined ? {} : { journal: deps.journal },
|
|
63
|
-
...generationRoute === undefined ? {} : { route: generationRoute },
|
|
64
|
-
}, {
|
|
65
|
-
sessionId,
|
|
66
|
-
session: input.session,
|
|
67
|
-
nodes: input.nodes,
|
|
68
|
-
trigger: 'manual',
|
|
69
|
-
...generationRoute === undefined ? {} : { route: generationRoute },
|
|
70
|
-
...input.signal === undefined ? {} : { signal: input.signal },
|
|
71
|
-
...systemSeq === undefined ? {} : { systemSeq },
|
|
72
|
-
});
|
|
73
|
-
const compactionId = `mc-${randomUUID()}`;
|
|
74
|
-
const summary = [{
|
|
75
|
-
type: 'text',
|
|
76
|
-
text: `${compactedPlaceholder(0).replace('§C0§', '§checkpoint§')}\n${digestText(draft)}`,
|
|
77
|
-
}];
|
|
78
|
-
const shadowedSeqs = input.nodes.map(node => node.seq);
|
|
79
|
-
const first = input.nodes[0];
|
|
80
|
-
const last = input.nodes[input.nodes.length - 1];
|
|
81
|
-
const shadowedTokenCount = input.nodes.reduce((total, node) => total + estimateTokens(node.text), 0);
|
|
82
|
-
// `Session.append` accepts an options argument only for *surface* event
|
|
83
|
-
// types; `compaction/*` are not among them, so these appends take two.
|
|
84
|
-
const startEvent = input.session.append('compaction/start', {
|
|
85
|
-
compactionId,
|
|
86
|
-
...input.sourceCommandId === undefined ? {} : { sourceCommandId: input.sourceCommandId },
|
|
87
|
-
turn: null,
|
|
88
|
-
});
|
|
89
|
-
const summaryEvent = input.session.append('compaction/summary', {
|
|
90
|
-
compactionId,
|
|
91
|
-
...input.sourceCommandId === undefined ? {} : { sourceCommandId: input.sourceCommandId },
|
|
92
|
-
summary,
|
|
93
|
-
shadowedRange: { start: first.seq, end: last.seq },
|
|
94
|
-
shadowedSeqs,
|
|
95
|
-
shadowedTokenCount,
|
|
96
|
-
provider: generationRoute?.provider ?? 'unknown',
|
|
97
|
-
model: generationRoute?.model ?? 'unknown',
|
|
98
|
-
maxTokens: policyNow().historianMaxTokens,
|
|
99
|
-
rawOutput: summary,
|
|
100
|
-
llmStreamCall: true,
|
|
101
|
-
});
|
|
102
|
-
// The replacement is appended synchronously after its metering event —
|
|
103
|
-
// the shared shadow-price protocol the session documents.
|
|
104
|
-
replaceSurfaceRange(input.session, first.seq, last.seq, summary, shadowedSeqs, syntheticNodeId('mc-checkpoint'), compactCheckpointSource(compactionId, input.sourceCommandId));
|
|
105
|
-
const endEvent = input.session.append('compaction/end', {
|
|
106
|
-
compactionId,
|
|
107
|
-
...input.sourceCommandId === undefined ? {} : { sourceCommandId: input.sourceCommandId },
|
|
108
|
-
turn: null,
|
|
109
|
-
});
|
|
110
|
-
deps.logger.info(`magic-context compaction: checkpoint over ${String(input.nodes.length)} nodes `
|
|
111
|
-
+ `(~${String(shadowedTokenCount)} tokens, importance ${String(draft.importance)})`);
|
|
112
|
-
deps.journal?.info('engine', `manual checkpoint over ${String(input.nodes.length)} nodes (~${String(shadowedTokenCount)} tokens)`, {
|
|
113
|
-
action: 'checkpoint',
|
|
114
|
-
compactionId,
|
|
115
|
-
sourceCommandId: input.sourceCommandId,
|
|
116
|
-
nodes: input.nodes.length,
|
|
117
|
-
shadowedTokenCount,
|
|
118
|
-
importance: draft.importance,
|
|
119
|
-
startSeq: startEvent.seq,
|
|
120
|
-
endSeq: endEvent.seq,
|
|
121
|
-
}, sessionId);
|
|
122
|
-
return {
|
|
123
|
-
compactionId,
|
|
124
|
-
...input.sourceCommandId === undefined ? {} : { sourceCommandId: input.sourceCommandId },
|
|
125
|
-
startSeq: startEvent.seq,
|
|
126
|
-
summarySeq: summaryEvent.seq,
|
|
127
|
-
endSeq: endEvent.seq,
|
|
128
|
-
summary,
|
|
129
|
-
shadowedRange: { start: first.seq, end: last.seq },
|
|
130
|
-
shadowedSeqs,
|
|
131
|
-
shadowedTokenCount,
|
|
132
|
-
};
|
|
133
|
-
};
|
|
134
|
-
const EngineClass = class MagicContextCompactionEngine extends base {
|
|
135
|
-
static inject = [];
|
|
136
|
-
constructor(engineCtx, config) {
|
|
137
|
-
super(engineCtx, config);
|
|
138
|
-
}
|
|
139
|
-
/** A stale engine (remounted composition) must no-op, never touch closed stores. */
|
|
140
|
-
usable() {
|
|
141
|
-
return deps.stores.closed !== true && deps.isDisposed?.() !== true;
|
|
142
|
-
}
|
|
143
|
-
/** The pressure path: reclaim, never a checkpoint (Magic Context's promise). */
|
|
144
|
-
async compactIfNeeded(agent) {
|
|
145
|
-
if (!this.usable())
|
|
146
|
-
return null;
|
|
147
|
-
const session = sessionOf(agent);
|
|
148
|
-
const sessionId = session.id;
|
|
149
|
-
try {
|
|
150
|
-
const generationRoute = routeNow();
|
|
151
|
-
runManagementPass({
|
|
152
|
-
session,
|
|
153
|
-
sessionId,
|
|
154
|
-
stores: deps.stores,
|
|
155
|
-
policy: policyNow(),
|
|
156
|
-
logger: deps.logger,
|
|
157
|
-
pass: { kind: 'execute', reason: 'execute-threshold' },
|
|
158
|
-
pressure: undefined,
|
|
159
|
-
...deps.llm === undefined ? {} : {
|
|
160
|
-
historian: {
|
|
161
|
-
llm: deps.llm,
|
|
162
|
-
...generationRoute === undefined ? {} : { route: generationRoute },
|
|
163
|
-
},
|
|
164
|
-
},
|
|
165
|
-
});
|
|
166
|
-
}
|
|
167
|
-
catch (error) {
|
|
168
|
-
// A failing pass must never escape into the host's step: warn, record,
|
|
169
|
-
// and let the session continue (the next threshold still retries).
|
|
170
|
-
const detail = errText(error);
|
|
171
|
-
deps.logger.warn(`magic-context compaction: management pass failed (${detail}); session continues`);
|
|
172
|
-
deps.journal?.warn('engine', `management pass failed: ${detail}`, {
|
|
173
|
-
action: 'pass-failed',
|
|
174
|
-
sessionId,
|
|
175
|
-
}, sessionId);
|
|
176
|
-
}
|
|
177
|
-
return null;
|
|
178
|
-
}
|
|
179
|
-
/** `/compact`: the user asked, so a real checkpoint is written. */
|
|
180
|
-
async compactNow(agent, signal, sourceCommandId) {
|
|
181
|
-
if (!this.usable())
|
|
182
|
-
return null;
|
|
183
|
-
const session = sessionOf(agent);
|
|
184
|
-
const nodes = enumerateSurfaceNodes(session);
|
|
185
|
-
const range = selectManualRange(nodes, deps.stores, session.id, policyNow());
|
|
186
|
-
if (range.length === 0)
|
|
187
|
-
return null;
|
|
188
|
-
return writeCheckpoint({
|
|
189
|
-
session,
|
|
190
|
-
nodes: range,
|
|
191
|
-
...sourceCommandId === undefined ? {} : { sourceCommandId },
|
|
192
|
-
signal,
|
|
193
|
-
});
|
|
194
|
-
}
|
|
195
|
-
async compactRegion(start, end, agent, signal) {
|
|
196
|
-
if (!this.usable())
|
|
197
|
-
throw new Error('compaction engine is shutting down');
|
|
198
|
-
const session = sessionOf(agent);
|
|
199
|
-
const nodes = regionNodes(enumerateSurfaceNodes(session), start, end);
|
|
200
|
-
if (nodes.length === 0)
|
|
201
|
-
throw new Error('compaction region contains no current surface nodes');
|
|
202
|
-
return writeCheckpoint({
|
|
203
|
-
session,
|
|
204
|
-
nodes,
|
|
205
|
-
...signal === undefined ? {} : { signal },
|
|
206
|
-
});
|
|
207
|
-
}
|
|
208
|
-
};
|
|
209
|
-
return await ctx.plugin(EngineClass, {});
|
|
210
|
-
}
|
|
211
|
-
/** The manual range: the same eligibility rules, without the token gate. */
|
|
212
|
-
function selectManualRange(nodes, stores, sessionId, policy) {
|
|
213
|
-
const covered = stores.coveredSeqs(sessionId);
|
|
214
|
-
const baselineNodeSeq = stores.baselineState(sessionId)?.nodeSeq;
|
|
215
|
-
const skippable = (node) => node.role === 'system'
|
|
216
|
-
|| node.seq === baselineNodeSeq
|
|
217
|
-
|| covered.has(node.seq)
|
|
218
|
-
|| node.isPlaceholder
|
|
219
|
-
|| /^\[(?:dropped|compacted|checkpoint) §/.test(node.text.trim().slice(0, 24))
|
|
220
|
-
|| !node.hasText;
|
|
221
|
-
let start = 0;
|
|
222
|
-
while (start < nodes.length && skippable(nodes[start]))
|
|
223
|
-
start += 1;
|
|
224
|
-
if (start >= nodes.length)
|
|
225
|
-
return [];
|
|
226
|
-
let cut = Math.max(start, nodes.length - Math.max(0, policy.historianProtectedNodes));
|
|
227
|
-
while (cut > start && nodes[cut]?.role === 'tool')
|
|
228
|
-
cut -= 1;
|
|
229
|
-
const slice = nodes.slice(start, cut);
|
|
230
|
-
return slice.length >= Math.max(2, policy.historianMinNodes) ? slice : [];
|
|
231
|
-
}
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
import { liveBoolean, liveNumber } from "./volatile.js";
|
|
2
|
-
import { vectorBackfillEnabled } from "./maintenance-wiring.js";
|
|
3
|
-
/** Every tracked switch. Booleans alarm on `went-off`; the rest report changes. */
|
|
4
|
-
export const SWITCH_KEYS = [
|
|
5
|
-
'write',
|
|
6
|
-
'autoPromote',
|
|
7
|
-
'embedBackfill',
|
|
8
|
-
'vectorBackfill',
|
|
9
|
-
'scoring',
|
|
10
|
-
'userRender',
|
|
11
|
-
'userCollect',
|
|
12
|
-
'userReview',
|
|
13
|
-
'machine',
|
|
14
|
-
'machineAutoStage',
|
|
15
|
-
'forceWaitMs',
|
|
16
|
-
];
|
|
17
|
-
/** The effective switch values for THIS mount, defaults already applied. */
|
|
18
|
-
export function buildSwitchSnapshot(config) {
|
|
19
|
-
return {
|
|
20
|
-
write: liveBoolean(config.memory?.write, true),
|
|
21
|
-
autoPromote: liveBoolean(config.memory?.autoPromote, true),
|
|
22
|
-
embedBackfill: liveBoolean(config.memory?.embedBackfill, true),
|
|
23
|
-
vectorBackfill: vectorBackfillEnabled(config.memory),
|
|
24
|
-
scoring: liveBoolean(config.memory?.scoring?.enabled, true),
|
|
25
|
-
userRender: liveBoolean(config.memory?.global?.user?.render, true),
|
|
26
|
-
userCollect: liveBoolean(config.memory?.global?.user?.collect, true),
|
|
27
|
-
userReview: liveBoolean(config.memory?.global?.user?.review, true),
|
|
28
|
-
machine: liveBoolean(config.memory?.global?.machine?.enabled, true),
|
|
29
|
-
machineAutoStage: liveBoolean(config.memory?.global?.machine?.autoStage, true),
|
|
30
|
-
// liveNumber unwraps schemastery volatile references — a raw read
|
|
31
|
-
// serialized the reference object into the boot row (measured 12:31: the
|
|
32
|
-
// retired guard-mode switch arrived as {"get":"[depth]"}). The unwrapping
|
|
33
|
-
// rule still applies to every volatile field here.
|
|
34
|
-
forceWaitMs: liveNumber(config.policy?.forceWaitReadyMs, 0),
|
|
35
|
-
};
|
|
36
|
-
}
|
|
37
|
-
/** Classify the movement between two snapshots; identical values produce no rows. */
|
|
38
|
-
export function diffSwitches(before, after) {
|
|
39
|
-
const rows = [];
|
|
40
|
-
for (const key of SWITCH_KEYS) {
|
|
41
|
-
// Snapshot values are only boolean | string | number by construction.
|
|
42
|
-
const was = before[key];
|
|
43
|
-
const now = after[key];
|
|
44
|
-
if (was === undefined || now === undefined || was === now)
|
|
45
|
-
continue;
|
|
46
|
-
if (typeof was === 'boolean' && typeof now === 'boolean') {
|
|
47
|
-
rows.push({ key, before: was, after: now, severity: was && !now ? 'went-off' : 'came-on' });
|
|
48
|
-
}
|
|
49
|
-
else {
|
|
50
|
-
rows.push({ key, before: was, after: now, severity: 'changed' });
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
return rows;
|
|
54
|
-
}
|
|
55
|
-
/** The meta-table key holding the JSON snapshot of the previous mount. */
|
|
56
|
-
export const SWITCH_SNAPSHOT_META_KEY = 'switch_snapshot';
|