@ijfw/memory-server 1.3.0 → 1.4.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.
Files changed (64) hide show
  1. package/fixtures/team/book.json +47 -0
  2. package/fixtures/team/business.json +47 -0
  3. package/fixtures/team/content.json +47 -0
  4. package/fixtures/team/design.json +47 -0
  5. package/fixtures/team/mixed.json +59 -0
  6. package/fixtures/team/research.json +47 -0
  7. package/fixtures/team/software.json +47 -0
  8. package/package.json +1 -9
  9. package/src/active-extension-writer.js +116 -0
  10. package/src/blackboard.js +360 -0
  11. package/src/cli-run.js +91 -0
  12. package/src/codex-agents.js +177 -0
  13. package/src/compute/extract.js +3 -0
  14. package/src/compute/fts5.js +4 -4
  15. package/src/compute/graph-lock.js +0 -2
  16. package/src/compute/migrations/003-tier-semantic.js +3 -3
  17. package/src/compute/runner.js +44 -15
  18. package/src/compute/schema.sql +1 -1
  19. package/src/cross-orchestrator-cli.js +974 -13
  20. package/src/cross-orchestrator.js +9 -1
  21. package/src/dashboard-client.html +144 -1
  22. package/src/dashboard-server.js +75 -2
  23. package/src/design-intelligence.js +721 -0
  24. package/src/dispatch/colon-syntax.js +31 -3
  25. package/src/dispatch/domain-manifest.js +251 -0
  26. package/src/dispatch/extension.js +404 -0
  27. package/src/dispatch/override.js +221 -0
  28. package/src/dispatch-planner.js +1 -0
  29. package/src/dream/runner.mjs +3 -3
  30. package/src/extension-installer.js +1230 -0
  31. package/src/extension-manifest-schema.js +301 -0
  32. package/src/extension-signer.js +740 -0
  33. package/src/gate-result-formatter.js +95 -0
  34. package/src/gate-result-schema.js +274 -0
  35. package/src/gate-result.js +195 -0
  36. package/src/intent-router.js +2 -0
  37. package/src/lib/npm-view.js +1 -0
  38. package/src/memory/fts5.js +3 -3
  39. package/src/memory/migrations/002-tier-semantic.js +2 -2
  40. package/src/memory/staleness.js +1 -1
  41. package/src/memory/tier-promotion.js +6 -6
  42. package/src/memory/tokenize.js +1 -1
  43. package/src/memory-feedback.js +188 -0
  44. package/src/override-manifest-schema.js +146 -0
  45. package/src/override-resolver.js +699 -0
  46. package/src/override-use-registry.js +307 -0
  47. package/src/overrides/presets/academic.md +101 -0
  48. package/src/overrides/presets/book.md +87 -0
  49. package/src/overrides/presets/campaign.md +95 -0
  50. package/src/overrides/presets/screenplay.md +99 -0
  51. package/src/recovery/checkpoint.js +191 -0
  52. package/src/redactor.js +2 -0
  53. package/src/runtime-mediator.js +178 -0
  54. package/src/sandbox.js +17 -3
  55. package/src/server.js +94 -2
  56. package/src/swarm/dispatch-prompt.js +154 -0
  57. package/src/swarm/planner.js +399 -0
  58. package/src/swarm/review.js +136 -0
  59. package/src/swarm/worktree.js +239 -0
  60. package/src/team/generator.js +119 -0
  61. package/src/team/schemas.js +341 -0
  62. package/src/trident/dispatch.js +47 -0
  63. package/src/update-check.js +1 -1
  64. package/src/vectors.js +7 -8
@@ -71,7 +71,6 @@ export function acquireGraphWriteLock(projectRoot, opts = {}) {
71
71
  const lp = lockPath(projectRoot);
72
72
 
73
73
  const deadline = Date.now() + waitMs;
74
- let _lastErr;
75
74
  while (true) {
76
75
  reclaimIfStale(lp);
77
76
  const payload = String(process.pid) + '\n' + String(Date.now()) + '\n';
@@ -86,7 +85,6 @@ export function acquireGraphWriteLock(projectRoot, opts = {}) {
86
85
  },
87
86
  };
88
87
  } catch (err) {
89
- lastErr = err;
90
88
  if (!err || err.code !== 'EEXIST') throw err;
91
89
  }
92
90
  if (Date.now() >= deadline) {
@@ -1,6 +1,6 @@
1
1
  // IJFW v1.3.0 -- compute migration 003: 4-tier semantic axis (D1).
2
2
  //
3
- // Source authority: PRD-v2 §9 Pillar D D1 + .planning/1.3.0/D-PILLAR-SPEC.md §1.
3
+ // Source authority: PRD-v2 section 9 Pillar D D1 + .planning/1.3.0/D-PILLAR-SPEC.md section 1.
4
4
  //
5
5
  // Bumps compute schema 2 -> 3. Adds `tier_semantic` to BOTH content tables
6
6
  // in the compute db so dream-cycle promotions (Episodic -> Semantic via
@@ -11,7 +11,7 @@
11
11
  // - raw.tier_semantic DEFAULT 'working' (raw observations are
12
12
  // session-bound by
13
13
  // definition; Working tier)
14
- // - compiled.tier_semantic DEFAULT 'semantic' (per D-PILLAR-SPEC §1 the
14
+ // - compiled.tier_semantic DEFAULT 'semantic' (per D-PILLAR-SPEC section 1 the
15
15
  // compiled table IS the
16
16
  // natural Semantic tier;
17
17
  // procedural_candidate /
@@ -40,7 +40,7 @@ export function up(db) {
40
40
  );
41
41
 
42
42
  // --- compiled.tier_semantic --------------------------------------------
43
- // Compiled rows are the natural Semantic tier per D-PILLAR-SPEC §1.
43
+ // Compiled rows are the natural Semantic tier per D-PILLAR-SPEC section 1.
44
44
  // Procedural candidate / procedural rows override the default at write
45
45
  // time. Episodic rows that get promoted to Semantic via supersession
46
46
  // also write into compiled with this default.
@@ -35,7 +35,7 @@
35
35
  import { spawn } from 'child_process';
36
36
  import {
37
37
  existsSync, mkdirSync, writeFileSync, appendFileSync,
38
- rmSync,
38
+ realpathSync, rmSync,
39
39
  } from 'fs';
40
40
  import { join, isAbsolute, resolve, sep } from 'path';
41
41
  import { homedir, tmpdir } from 'os';
@@ -138,27 +138,51 @@ function resolveLogDir(sessionId, projectRoot) {
138
138
  return { dir: null, ok: false };
139
139
  }
140
140
 
141
- // Path-prefix check: warn the caller if they passed an allowedPaths entry
142
- // that escapes the project root or cwd. The OS wrapper does real enforcement;
143
- // this is purely a developer-experience surface.
144
- function validateAllowedPaths({ projectRoot, cwd, allowedPaths }) {
141
+ function canonicalPath(p) {
142
+ const resolved = resolve(p);
143
+ try {
144
+ return realpathSync(resolved);
145
+ } catch {
146
+ return resolved;
147
+ }
148
+ }
149
+
150
+ function isPathWithin(pathname, root) {
151
+ if (!pathname || !root) return false;
152
+ const child = resolve(pathname);
153
+ const parent = resolve(root);
154
+ return child === parent || child.startsWith(parent + sep);
155
+ }
156
+
157
+ // Normalize caller-supplied write allow-list paths before they reach the OS
158
+ // sandbox. Symlinks are resolved first so a project-local link to /tmp or $HOME
159
+ // cannot smuggle an outside write root into sandbox-exec/nsjail/bwrap.
160
+ function normalizeAllowedPaths({ projectRoot, cwd, allowedPaths }) {
145
161
  const warnings = [];
162
+ const safePaths = [];
163
+ const projectReal = projectRoot ? canonicalPath(projectRoot) : null;
164
+ const cwdReal = cwd ? canonicalPath(cwd) : null;
165
+
146
166
  for (const p of allowedPaths || []) {
147
167
  if (!isAbsolute(p)) {
148
168
  warnings.push(`allowedPaths entry "${p}" is not absolute -- ignoring.`);
149
169
  continue;
150
170
  }
151
- const norm = resolve(p);
152
- const inProject = projectRoot && norm.startsWith(projectRoot + sep);
153
- const inCwd = cwd && norm.startsWith(cwd + sep);
154
- if (!inProject && !inCwd && norm !== projectRoot && norm !== cwd) {
171
+
172
+ const requested = resolve(p);
173
+ const norm = canonicalPath(requested);
174
+ const inProject = isPathWithin(norm, projectReal);
175
+ const inCwd = isPathWithin(norm, cwdReal);
176
+ if (!inProject && !inCwd) {
155
177
  warnings.push(
156
- `allowedPaths entry "${norm}" is outside cwd and projectRoot. ` +
157
- 'OS sandbox enforcement may still block; this is a best-effort warning.'
178
+ `allowedPaths entry "${requested}" resolves outside cwd and projectRoot -- ignoring.`
158
179
  );
180
+ continue;
159
181
  }
182
+ safePaths.push(norm);
160
183
  }
161
- return warnings;
184
+
185
+ return { allowedPaths: Array.from(new Set(safePaths)), warnings };
162
186
  }
163
187
 
164
188
  function makeTempDir() {
@@ -199,7 +223,6 @@ export async function runCompute(opts = {}) {
199
223
  const timeoutMs = clampTimeout(opts.timeoutMs);
200
224
  const allowNet = !!opts.allowNet;
201
225
  const vmOnly = !!opts.vmOnly;
202
- const allowedPaths = (opts.allowedPaths || []).map((p) => resolve(p));
203
226
  const sessionId = String(opts.sessionId || newSessionId());
204
227
 
205
228
  // vm.Script JS-only path -- short-circuit before spawn.
@@ -275,8 +298,13 @@ export async function runCompute(opts = {}) {
275
298
  }
276
299
 
277
300
  const env = scrubEnv();
278
- // Best-effort warnings for caller-supplied allowedPaths.
279
- const pathWarnings = validateAllowedPaths({ projectRoot, cwd: tempDir, allowedPaths });
301
+ const allowedPathResult = normalizeAllowedPaths({
302
+ projectRoot,
303
+ cwd: tempDir,
304
+ allowedPaths: opts.allowedPaths || [],
305
+ });
306
+ const allowedPaths = allowedPathResult.allowedPaths;
307
+ const pathWarnings = allowedPathResult.warnings;
280
308
  for (const w of pathWarnings) {
281
309
  writeLog(`[allowlist-warning] ${w}\n`);
282
310
  }
@@ -414,3 +442,4 @@ export async function runCompute(opts = {}) {
414
442
 
415
443
  // Re-export for tests.
416
444
  export { resolvePython, detectSandbox };
445
+ export const __test = { normalizeAllowedPaths };
@@ -7,7 +7,7 @@
7
7
  -- memory (empty in alpha), `trident_run` for C1 KS-stat convergence-stop.
8
8
  -- See ADR for migration triggers + risk assessment.
9
9
  --
10
- -- v2 additions (PRD §9 Pillar C9.4 + C9.6):
10
+ -- v2 additions (PRD section 9 Pillar C9.4 + C9.6):
11
11
  -- - FTS5 tokenizer flipped to `porter unicode61` so morphological
12
12
  -- variants ("authenticate"/"authenticating"/"running"/"ran") collapse
13
13
  -- to a shared stem. Migration 002 recreates raw_fts + compiled_fts.