@principles/core 1.212.0 → 1.214.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/dist/runtime-v2/__tests__/architecture-regression.test.js +67 -20
- package/dist/runtime-v2/__tests__/architecture-regression.test.js.map +1 -1
- package/dist/runtime-v2/activation/memory-approval-store.js +1 -1
- package/dist/runtime-v2/activation/memory-approval-store.js.map +1 -1
- package/dist/runtime-v2/activation/sqlite-approval-store.d.ts.map +1 -1
- package/dist/runtime-v2/activation/sqlite-approval-store.js +9 -1
- package/dist/runtime-v2/activation/sqlite-approval-store.js.map +1 -1
- package/dist/runtime-v2/adapter/openclaw-cli-runtime-adapter.js +1 -1
- package/dist/runtime-v2/adapter/openclaw-cli-runtime-adapter.js.map +1 -1
- package/dist/runtime-v2/adapter/pi-ai-runtime-adapter.js +2 -2
- package/dist/runtime-v2/adapter/pi-ai-runtime-adapter.js.map +1 -1
- package/dist/runtime-v2/control-plane-triage.js +2 -2
- package/dist/runtime-v2/control-plane-triage.js.map +1 -1
- package/dist/runtime-v2/error-categories.js +1 -1
- package/dist/runtime-v2/error-categories.js.map +1 -1
- package/dist/runtime-v2/golden-trace.js +1 -1
- package/dist/runtime-v2/golden-trace.js.map +1 -1
- package/dist/runtime-v2/internalization/intake-to-internalization-bridge.d.ts.map +1 -1
- package/dist/runtime-v2/internalization/intake-to-internalization-bridge.js +1 -0
- package/dist/runtime-v2/internalization/intake-to-internalization-bridge.js.map +1 -1
- package/dist/runtime-v2/pain-signal-bridge.d.ts.map +1 -1
- package/dist/runtime-v2/pain-signal-bridge.js +1 -0
- package/dist/runtime-v2/pain-signal-bridge.js.map +1 -1
- package/dist/runtime-v2/pain-signal-runtime-factory.d.ts.map +1 -1
- package/dist/runtime-v2/pain-signal-runtime-factory.js +1 -0
- package/dist/runtime-v2/pain-signal-runtime-factory.js.map +1 -1
- package/dist/runtime-v2/store/commit/diagnostician-committer.d.ts.map +1 -1
- package/dist/runtime-v2/store/commit/diagnostician-committer.js +1 -0
- package/dist/runtime-v2/store/commit/diagnostician-committer.js.map +1 -1
- package/dist/runtime-v2/store/context/resilient-context-assembler.js +1 -1
- package/dist/runtime-v2/store/context/resilient-context-assembler.js.map +1 -1
- package/package.json +1 -1
|
@@ -3236,29 +3236,49 @@ describe('PRI-450 / PRI-462: core I/O seam registry guard', () => {
|
|
|
3236
3236
|
const ALLOWED_IO_FILES = new Set(isValidRegistry(registry)
|
|
3237
3237
|
? registry.seams.flatMap((s) => s.files)
|
|
3238
3238
|
: []);
|
|
3239
|
-
// Extract all import module paths from source code.
|
|
3239
|
+
// Extract all RUNTIME import module paths from source code.
|
|
3240
3240
|
// Handles: import ... from 'mod', import 'mod' (side-effect), and multiline imports.
|
|
3241
|
-
//
|
|
3241
|
+
// EXCLUDES `import type ... from` — type-only imports are erased at compile time
|
|
3242
|
+
// and do not introduce runtime I/O. Reuses the same pattern proven in the
|
|
3243
|
+
// PRI-215 extractImportModulePaths helper.
|
|
3244
|
+
//
|
|
3245
|
+
// The negative lookahead `(?!type\b)` after `import\s+` prevents matching
|
|
3246
|
+
// `import type { X } from 'mod'` and `import type X from 'mod'`.
|
|
3242
3247
|
function extractImportPaths(src) {
|
|
3243
3248
|
const paths = [];
|
|
3244
|
-
|
|
3249
|
+
// `import ... from 'mod'` — but NOT `import type ... from 'mod'`.
|
|
3250
|
+
for (const m of src.matchAll(/import\s+(?!type\b)[\s\S]*?from\s+['"]([^'"]+)['"]/g)) {
|
|
3245
3251
|
if (m[1] != null)
|
|
3246
3252
|
paths.push(m[1]);
|
|
3247
3253
|
}
|
|
3248
|
-
|
|
3254
|
+
// Side-effect `import 'mod'` — `import type 'mod'` is not valid TS so no
|
|
3255
|
+
// exclusion needed, but the lookahead keeps it defensive.
|
|
3256
|
+
for (const m of src.matchAll(/import\s+(?!type\b)['"]([^'"]+)['"]/g)) {
|
|
3249
3257
|
if (m[1] != null && !paths.includes(m[1]))
|
|
3250
3258
|
paths.push(m[1]);
|
|
3251
3259
|
}
|
|
3252
3260
|
return paths;
|
|
3253
3261
|
}
|
|
3254
|
-
// Check if any import path references
|
|
3255
|
-
|
|
3262
|
+
// Check if any runtime import path references a Node I/O module.
|
|
3263
|
+
// Covers fs, path, child_process, better-sqlite3 (including sub-paths like fs/promises).
|
|
3264
|
+
// Type-only imports (`import type ... from 'fs'`) are excluded by extractImportPaths.
|
|
3265
|
+
//
|
|
3266
|
+
// This MUST stay in sync with eslint.config.js `no-restricted-imports` patterns.
|
|
3267
|
+
// ESLint uses `allowTypeImports: true` for child_process/better-sqlite3, so the
|
|
3268
|
+
// arch test is the runtime-I/O backstop for those modules.
|
|
3269
|
+
function importsNodeIo(src) {
|
|
3256
3270
|
const paths = extractImportPaths(src);
|
|
3257
3271
|
return paths.some((p) => p === 'fs' || p.startsWith('fs/') ||
|
|
3258
3272
|
p === 'node:fs' || p.startsWith('node:fs/') ||
|
|
3259
3273
|
p === 'path' || p.startsWith('path/') ||
|
|
3260
|
-
p === 'node:path' || p.startsWith('node:path/')
|
|
3274
|
+
p === 'node:path' || p.startsWith('node:path/') ||
|
|
3275
|
+
p === 'child_process' || p.startsWith('child_process/') ||
|
|
3276
|
+
p === 'node:child_process' || p.startsWith('node:child_process/') ||
|
|
3277
|
+
p === 'better-sqlite3');
|
|
3261
3278
|
}
|
|
3279
|
+
// Back-compat alias: keep the old name working for any external callers/tests
|
|
3280
|
+
// that referenced importsFsOrPath directly. New code should use importsNodeIo.
|
|
3281
|
+
const importsFsOrPath = importsNodeIo;
|
|
3262
3282
|
function collectTsFiles(dir, acc) {
|
|
3263
3283
|
const entries = fsSync.readdirSync(dir, { withFileTypes: true });
|
|
3264
3284
|
for (const entry of entries) {
|
|
@@ -3319,14 +3339,14 @@ describe('PRI-450 / PRI-462: core I/O seam registry guard', () => {
|
|
|
3319
3339
|
expect(weak).toEqual([]);
|
|
3320
3340
|
});
|
|
3321
3341
|
// ── Registry ↔ production files (PRI-450, EP-02) ──────────────────────────
|
|
3322
|
-
it('core/src/ production files: only registry-listed files import fs/path', () => {
|
|
3342
|
+
it('core/src/ production files: only registry-listed files import Node I/O modules (fs/path/child_process/better-sqlite3)', () => {
|
|
3323
3343
|
const coreSrcDir = pathSync.resolve(__dirname, '..', '..');
|
|
3324
3344
|
const allFiles = [];
|
|
3325
3345
|
collectTsFiles(coreSrcDir, allFiles);
|
|
3326
3346
|
const violations = [];
|
|
3327
3347
|
for (const filePath of allFiles) {
|
|
3328
3348
|
const content = fsSync.readFileSync(filePath, 'utf-8');
|
|
3329
|
-
if (
|
|
3349
|
+
if (importsNodeIo(content)) {
|
|
3330
3350
|
const relPath = pathSync.relative(coreSrcDir, filePath).replace(/\\/g, '/');
|
|
3331
3351
|
if (!ALLOWED_IO_FILES.has(relPath)) {
|
|
3332
3352
|
violations.push(relPath);
|
|
@@ -3334,8 +3354,9 @@ describe('PRI-450 / PRI-462: core I/O seam registry guard', () => {
|
|
|
3334
3354
|
}
|
|
3335
3355
|
}
|
|
3336
3356
|
if (violations.length > 0) {
|
|
3337
|
-
throw new Error(`Found ${violations.length} file(s) importing fs/path that are NOT in io-seam-registry.json.\n` +
|
|
3357
|
+
throw new Error(`Found ${violations.length} file(s) importing fs/path/child_process/better-sqlite3 that are NOT in io-seam-registry.json.\n` +
|
|
3338
3358
|
`Add them to the appropriate seam in packages/principles-core/io-seam-registry.json.\n` +
|
|
3359
|
+
`Note: \`import type\` from these modules is allowed (erased at runtime) and won't trigger this.\n` +
|
|
3339
3360
|
`Violations:\n ` + violations.join('\n '));
|
|
3340
3361
|
}
|
|
3341
3362
|
});
|
|
@@ -3363,19 +3384,45 @@ describe('PRI-450 / PRI-462: core I/O seam registry guard', () => {
|
|
|
3363
3384
|
expect(eslintSrc).toContain('io-seam-registry.json');
|
|
3364
3385
|
});
|
|
3365
3386
|
// ── Helper unit tests ─────────────────────────────────────────────────────
|
|
3366
|
-
it('
|
|
3387
|
+
it('importsNodeIo detects sub-path imports (fs/promises) and side-effect imports', () => {
|
|
3367
3388
|
// Sub-path import
|
|
3368
|
-
expect(
|
|
3369
|
-
expect(
|
|
3389
|
+
expect(importsNodeIo(`import { mkdir } from 'node:fs/promises';`)).toBe(true);
|
|
3390
|
+
expect(importsNodeIo(`import { posix } from 'path/posix';`)).toBe(true);
|
|
3370
3391
|
// Side-effect import
|
|
3371
|
-
expect(
|
|
3372
|
-
expect(
|
|
3392
|
+
expect(importsNodeIo(`import 'fs';`)).toBe(true);
|
|
3393
|
+
expect(importsNodeIo(`import "node:path";`)).toBe(true);
|
|
3373
3394
|
// Standard import
|
|
3374
|
-
expect(
|
|
3375
|
-
expect(
|
|
3376
|
-
// Non-
|
|
3377
|
-
expect(
|
|
3378
|
-
expect(
|
|
3395
|
+
expect(importsNodeIo(`import * as fs from 'fs';`)).toBe(true);
|
|
3396
|
+
expect(importsNodeIo(`import { resolve } from 'node:path';`)).toBe(true);
|
|
3397
|
+
// Non-I/O imports
|
|
3398
|
+
expect(importsNodeIo(`import { foo } from 'bar';`)).toBe(false);
|
|
3399
|
+
expect(importsNodeIo(``)).toBe(false);
|
|
3400
|
+
});
|
|
3401
|
+
it('importsNodeIo detects child_process and better-sqlite3 runtime imports', () => {
|
|
3402
|
+
// Runtime child_process imports
|
|
3403
|
+
expect(importsNodeIo(`import { spawn } from 'child_process';`)).toBe(true);
|
|
3404
|
+
expect(importsNodeIo(`import { execSync } from 'node:child_process';`)).toBe(true);
|
|
3405
|
+
expect(importsNodeIo(`import { fork } from 'child_process/promises';`)).toBe(true);
|
|
3406
|
+
// Runtime better-sqlite3 import
|
|
3407
|
+
expect(importsNodeIo(`import Database from 'better-sqlite3';`)).toBe(true);
|
|
3408
|
+
// Mixed runtime + type import from child_process (still runtime I/O)
|
|
3409
|
+
expect(importsNodeIo(`import { spawn, type SpawnOptions } from 'child_process';`)).toBe(true);
|
|
3410
|
+
});
|
|
3411
|
+
it('importsNodeIo EXCLUDES `import type` (erased at runtime, no I/O)', () => {
|
|
3412
|
+
// Type-only imports from forbidden modules — must NOT trigger
|
|
3413
|
+
expect(importsNodeIo(`import type { Database } from 'better-sqlite3';`)).toBe(false);
|
|
3414
|
+
expect(importsNodeIo(`import type BetterSqlite3 from 'better-sqlite3';`)).toBe(false);
|
|
3415
|
+
expect(importsNodeIo(`import type { SpawnOptions } from 'child_process';`)).toBe(false);
|
|
3416
|
+
expect(importsNodeIo(`import type { Stats } from 'node:fs';`)).toBe(false);
|
|
3417
|
+
expect(importsNodeIo(`import type { Platform } from 'node:process';`)).toBe(false);
|
|
3418
|
+
// Mixed: a real `import type` next to a runtime import from a DIFFERENT module
|
|
3419
|
+
// — the type import is excluded, the runtime import is detected.
|
|
3420
|
+
expect(importsNodeIo(`import type { Database } from 'better-sqlite3';\nimport { spawn } from 'child_process';`)).toBe(true);
|
|
3421
|
+
});
|
|
3422
|
+
it('importsFsOrPath alias stays in sync with importsNodeIo', () => {
|
|
3423
|
+
// The back-compat alias must point to the same implementation.
|
|
3424
|
+
expect(importsFsOrPath(`import { spawn } from 'child_process';`)).toBe(true);
|
|
3425
|
+
expect(importsFsOrPath(`import type { Database } from 'better-sqlite3';`)).toBe(false);
|
|
3379
3426
|
});
|
|
3380
3427
|
});
|
|
3381
3428
|
//# sourceMappingURL=architecture-regression.test.js.map
|