instar 1.3.647 → 1.3.648
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/commands/reflect.d.ts.map +1 -1
- package/dist/commands/reflect.js +7 -3
- package/dist/commands/reflect.js.map +1 -1
- package/dist/commands/server.d.ts.map +1 -1
- package/dist/commands/server.js +35 -0
- package/dist/commands/server.js.map +1 -1
- package/dist/commands/setup.d.ts.map +1 -1
- package/dist/commands/setup.js +17 -0
- package/dist/commands/setup.js.map +1 -1
- package/dist/config/ConfigDefaults.d.ts.map +1 -1
- package/dist/config/ConfigDefaults.js +14 -0
- package/dist/config/ConfigDefaults.js.map +1 -1
- package/dist/core/CoherenceGate.d.ts.map +1 -1
- package/dist/core/CoherenceGate.js +24 -0
- package/dist/core/CoherenceGate.js.map +1 -1
- package/dist/core/CoherenceReviewer.d.ts +9 -0
- package/dist/core/CoherenceReviewer.d.ts.map +1 -1
- package/dist/core/CoherenceReviewer.js +18 -2
- package/dist/core/CoherenceReviewer.js.map +1 -1
- package/dist/core/InputGuard.d.ts.map +1 -1
- package/dist/core/InputGuard.js +17 -3
- package/dist/core/InputGuard.js.map +1 -1
- package/dist/core/MessageSentinel.d.ts.map +1 -1
- package/dist/core/MessageSentinel.js +19 -2
- package/dist/core/MessageSentinel.js.map +1 -1
- package/dist/core/MessagingToneGate.d.ts +8 -0
- package/dist/core/MessagingToneGate.d.ts.map +1 -1
- package/dist/core/MessagingToneGate.js +16 -1
- package/dist/core/MessagingToneGate.js.map +1 -1
- package/dist/core/PostUpdateMigrator.d.ts.map +1 -1
- package/dist/core/PostUpdateMigrator.js +10 -0
- package/dist/core/PostUpdateMigrator.js.map +1 -1
- package/dist/core/SingleInstanceLock.d.ts +103 -0
- package/dist/core/SingleInstanceLock.d.ts.map +1 -0
- package/dist/core/SingleInstanceLock.js +300 -0
- package/dist/core/SingleInstanceLock.js.map +1 -0
- package/dist/core/SpawnCapIntelligenceProvider.d.ts +89 -0
- package/dist/core/SpawnCapIntelligenceProvider.d.ts.map +1 -0
- package/dist/core/SpawnCapIntelligenceProvider.js +164 -0
- package/dist/core/SpawnCapIntelligenceProvider.js.map +1 -0
- package/dist/core/hostSpawnSemaphore.d.ts +188 -0
- package/dist/core/hostSpawnSemaphore.d.ts.map +1 -0
- package/dist/core/hostSpawnSemaphore.js +471 -0
- package/dist/core/hostSpawnSemaphore.js.map +1 -0
- package/dist/core/intelligenceProviderFactory.d.ts +0 -12
- package/dist/core/intelligenceProviderFactory.d.ts.map +1 -1
- package/dist/core/intelligenceProviderFactory.js +27 -9
- package/dist/core/intelligenceProviderFactory.js.map +1 -1
- package/dist/core/types.d.ts +18 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js.map +1 -1
- package/dist/scaffold/templates.d.ts.map +1 -1
- package/dist/scaffold/templates.js +5 -0
- package/dist/scaffold/templates.js.map +1 -1
- package/dist/server/CapabilityIndex.d.ts.map +1 -1
- package/dist/server/CapabilityIndex.js +9 -0
- package/dist/server/CapabilityIndex.js.map +1 -1
- package/dist/server/routes.d.ts.map +1 -1
- package/dist/server/routes.js +28 -0
- package/dist/server/routes.js.map +1 -1
- package/package.json +4 -2
- package/scripts/lint-no-direct-destructive.js +4 -0
- package/scripts/lint-no-unbounded-llm-spawn.js +137 -0
- package/src/data/builtin-manifest.json +63 -63
- package/src/scaffold/templates.ts +5 -0
- package/upgrades/1.3.648.md +99 -0
- package/upgrades/side-effects/forkbomb-prevention-simple.md +138 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "instar",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.648",
|
|
4
4
|
"description": "Coherence infrastructure for self-evolving AI agents — on the Claude Code or Codex subscription you already have.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -28,7 +28,9 @@
|
|
|
28
28
|
"test:contract": "node scripts/run-contract-tests.js",
|
|
29
29
|
"test:contract:raw": "vitest run --config vitest.contract.config.ts",
|
|
30
30
|
"test:all": "vitest run && vitest run --config vitest.integration.config.ts && vitest run --config vitest.e2e.config.ts",
|
|
31
|
-
"lint": "tsc --noEmit && node scripts/lint-no-direct-destructive.js && node scripts/lint-no-direct-llm-http.js && node scripts/lint-no-direct-url-log.js && node scripts/lint-no-unfunneled-topic-creation.js && node scripts/lint-no-unfunneled-headless-launch.js && node scripts/lint-no-unfunneled-credential-write.js && node scripts/lint-state-registry.js && node scripts/lint-store-retention-declared.js && node scripts/lint-no-wholefile-sync-read.js && node scripts/lint-cas-emit-placement.js && node scripts/lint-journal-actuation-ban.js && node scripts/lint-no-blocking-process-scans.js && node scripts/lint-sync-subprocess-chokepoint.js && node scripts/lint-dev-agent-dark-gate.js && node scripts/lint-guard-manifest.js && node scripts/lint-llm-attribution.js && node scripts/lint-no-mainthread-cartographer-walk.js && node scripts/lint-scrape-fixture-realness.js && node scripts/check-codex-rule1-drift.js",
|
|
31
|
+
"lint": "tsc --noEmit && node scripts/lint-no-direct-destructive.js && node scripts/lint-no-direct-llm-http.js && node scripts/lint-no-direct-url-log.js && node scripts/lint-no-unfunneled-topic-creation.js && node scripts/lint-no-unfunneled-headless-launch.js && node scripts/lint-no-unbounded-llm-spawn.js && node scripts/lint-no-unfunneled-credential-write.js && node scripts/lint-state-registry.js && node scripts/lint-store-retention-declared.js && node scripts/lint-no-wholefile-sync-read.js && node scripts/lint-cas-emit-placement.js && node scripts/lint-journal-actuation-ban.js && node scripts/lint-no-blocking-process-scans.js && node scripts/lint-sync-subprocess-chokepoint.js && node scripts/lint-dev-agent-dark-gate.js && node scripts/lint-guard-manifest.js && node scripts/lint-llm-attribution.js && node scripts/lint-no-mainthread-cartographer-walk.js && node scripts/lint-scrape-fixture-realness.js && node scripts/check-codex-rule1-drift.js",
|
|
32
|
+
"lint:no-unbounded-llm-spawn": "node scripts/lint-no-unbounded-llm-spawn.js",
|
|
33
|
+
"lint:no-unbounded-llm-spawn:staged": "node scripts/lint-no-unbounded-llm-spawn.js --staged",
|
|
32
34
|
"lint:destructive": "node scripts/lint-no-direct-destructive.js",
|
|
33
35
|
"lint:dev-agent-dark-gate": "node scripts/lint-dev-agent-dark-gate.js",
|
|
34
36
|
"lint:guard-manifest": "node scripts/lint-guard-manifest.js",
|
|
@@ -86,6 +86,10 @@ const ALLOWLIST = new Set([
|
|
|
86
86
|
// Same bootstrap-escape pattern (june15-headless-spawn-reroute funnel
|
|
87
87
|
// lint) — read-only `git diff --cached --name-only` only.
|
|
88
88
|
'scripts/lint-no-unfunneled-headless-launch.js',
|
|
89
|
+
// Same bootstrap-escape pattern (fork-bomb spawn-cap funnel lint) —
|
|
90
|
+
// read-only `git diff --cached --name-only` for --staged. Cannot depend on
|
|
91
|
+
// the TS funnel because TS is not compiled when the lint runs in pre-push.
|
|
92
|
+
'scripts/lint-no-unbounded-llm-spawn.js',
|
|
89
93
|
// Same bootstrap-escape pattern (Step 4b credential-write funnel lint) —
|
|
90
94
|
// read-only `git diff --cached --name-only` for --staged. Cannot depend on
|
|
91
95
|
// the TS funnel because TS is not compiled when the lint runs in pre-push.
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* lint-no-unbounded-llm-spawn.js — refuses a raw LLM-CLI provider construction
|
|
4
|
+
* outside the spawn-cap funnel.
|
|
5
|
+
*
|
|
6
|
+
* Part of the SIMPLE fork-bomb prevention design
|
|
7
|
+
* (docs/specs/forkbomb-prevention-simple.md §P1). The host-wide concurrent-spawn
|
|
8
|
+
* cap is enforced by the SpawnCapIntelligenceProvider wrapper, which is installed
|
|
9
|
+
* at EVERY return arm of `buildIntelligenceProvider` (the factory funnel). Any
|
|
10
|
+
* code that constructs an LLM-CLI provider DIRECTLY —
|
|
11
|
+
* new ClaudeCliIntelligenceProvider(...)
|
|
12
|
+
* new CodexCliIntelligenceProvider(...)
|
|
13
|
+
* new GeminiCliIntelligenceProvider(...)
|
|
14
|
+
* new PiCliIntelligenceProvider(...)
|
|
15
|
+
* — bypasses that wrapper, re-introducing an UN-CAPPED spawn path: the exact
|
|
16
|
+
* 2026-06-20 fork-bomb vector (one `claude -p` per call, zero concurrency
|
|
17
|
+
* control). That bypass must fail CI, not be discovered on the next OOM.
|
|
18
|
+
*
|
|
19
|
+
* RULE: outside the allowlist below, no source file may construct one of those
|
|
20
|
+
* providers directly. Route through `buildIntelligenceProvider(...)` (the
|
|
21
|
+
* factory), which applies the spawn cap + circuit breaker.
|
|
22
|
+
*
|
|
23
|
+
* Exit codes: 0 — clean; 1 — at least one violation.
|
|
24
|
+
*
|
|
25
|
+
* Usage:
|
|
26
|
+
* node scripts/lint-no-unbounded-llm-spawn.js # full repo
|
|
27
|
+
* node scripts/lint-no-unbounded-llm-spawn.js --staged # staged files
|
|
28
|
+
*/
|
|
29
|
+
|
|
30
|
+
import fs from 'node:fs';
|
|
31
|
+
import path from 'node:path';
|
|
32
|
+
import { execSync } from 'node:child_process';
|
|
33
|
+
import { fileURLToPath } from 'node:url';
|
|
34
|
+
|
|
35
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
36
|
+
const ROOT = path.resolve(path.dirname(__filename), '..');
|
|
37
|
+
|
|
38
|
+
// The LLM-CLI provider classes — constructing any of them is a SPAWN-capable
|
|
39
|
+
// path (their evaluate() shells out to the CLI binary).
|
|
40
|
+
const PROVIDER_CLASSES = [
|
|
41
|
+
'ClaudeCliIntelligenceProvider',
|
|
42
|
+
'CodexCliIntelligenceProvider',
|
|
43
|
+
'GeminiCliIntelligenceProvider',
|
|
44
|
+
'PiCliIntelligenceProvider',
|
|
45
|
+
];
|
|
46
|
+
|
|
47
|
+
// ── Allowlist (closed). Adding an entry requires review of WHY the callsite
|
|
48
|
+
// cannot route through buildIntelligenceProvider() (where the spawn-cap
|
|
49
|
+
// wrapper is installed), and how its spawn is otherwise bounded. ─────────
|
|
50
|
+
const ALLOWLIST = new Set([
|
|
51
|
+
// THE funnel — the spawn-cap wrapper is installed here, around every
|
|
52
|
+
// construction (wrapForFunnel).
|
|
53
|
+
'src/core/intelligenceProviderFactory.ts',
|
|
54
|
+
// The provider definitions themselves (their own class bodies).
|
|
55
|
+
'src/core/ClaudeCliIntelligenceProvider.ts',
|
|
56
|
+
'src/core/CodexCliIntelligenceProvider.ts',
|
|
57
|
+
'src/core/GeminiCliIntelligenceProvider.ts',
|
|
58
|
+
'src/core/PiCliIntelligenceProvider.ts',
|
|
59
|
+
// This lint file mentions the symbols it greps for.
|
|
60
|
+
'scripts/lint-no-unbounded-llm-spawn.js',
|
|
61
|
+
]);
|
|
62
|
+
|
|
63
|
+
const SCAN_DIRS = ['src', 'scripts', 'templates'];
|
|
64
|
+
const EXTENSIONS = new Set(['.ts', '.tsx', '.js', '.mjs', '.cjs']);
|
|
65
|
+
|
|
66
|
+
// `new <ProviderClass>(` — the construction. An IMPORT of the class is fine
|
|
67
|
+
// (the factory imports them); only a direct `new …(` outside the funnel is a
|
|
68
|
+
// bypass.
|
|
69
|
+
const PATTERNS = PROVIDER_CLASSES.map((cls) => new RegExp(`\\bnew\\s+${cls}\\s*\\(`));
|
|
70
|
+
|
|
71
|
+
function listFiles() {
|
|
72
|
+
const staged = process.argv.includes('--staged');
|
|
73
|
+
if (staged) {
|
|
74
|
+
const out = execSync('git diff --cached --name-only', { cwd: ROOT, encoding: 'utf-8' });
|
|
75
|
+
return out.split('\n').filter(Boolean);
|
|
76
|
+
}
|
|
77
|
+
const explicit = process.argv.slice(2).filter((a) => !a.startsWith('--'));
|
|
78
|
+
if (explicit.length) return explicit;
|
|
79
|
+
|
|
80
|
+
const files = [];
|
|
81
|
+
const walk = (dir) => {
|
|
82
|
+
let entries;
|
|
83
|
+
try {
|
|
84
|
+
entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
85
|
+
} catch {
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
for (const e of entries) {
|
|
89
|
+
if (e.name === 'node_modules' || e.name === '.git' || e.name === 'dist') continue;
|
|
90
|
+
const full = path.join(dir, e.name);
|
|
91
|
+
if (e.isDirectory()) walk(full);
|
|
92
|
+
else if (EXTENSIONS.has(path.extname(e.name))) files.push(path.relative(ROOT, full));
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
for (const d of SCAN_DIRS) walk(path.join(ROOT, d));
|
|
96
|
+
return files;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
let violations = 0;
|
|
100
|
+
for (const rel of listFiles()) {
|
|
101
|
+
const normalized = rel.split(path.sep).join('/');
|
|
102
|
+
if (ALLOWLIST.has(normalized)) continue;
|
|
103
|
+
if (!EXTENSIONS.has(path.extname(normalized))) continue;
|
|
104
|
+
// Test files exercise the providers directly with stubs / real spawns under
|
|
105
|
+
// controlled conditions — they are not a production spawn path.
|
|
106
|
+
if (/(^|\/)tests\//.test(normalized) || /\.test\.[cm]?[jt]sx?$/.test(normalized)) continue;
|
|
107
|
+
const full = path.isAbsolute(normalized) ? normalized : path.join(ROOT, normalized);
|
|
108
|
+
let content;
|
|
109
|
+
try {
|
|
110
|
+
content = fs.readFileSync(full, 'utf-8');
|
|
111
|
+
} catch {
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
const lines = content.split('\n');
|
|
115
|
+
for (let i = 0; i < lines.length; i++) {
|
|
116
|
+
// Comment-only mentions are documentation, not a construction.
|
|
117
|
+
const trimmed = lines[i].trimStart();
|
|
118
|
+
if (/^(\/\/|\*|\/\*|#)/.test(trimmed)) continue;
|
|
119
|
+
for (const pattern of PATTERNS) {
|
|
120
|
+
if (pattern.test(lines[i])) {
|
|
121
|
+
console.error(
|
|
122
|
+
`${normalized}:${i + 1} — direct LLM-CLI provider construction outside the spawn-cap funnel. ` +
|
|
123
|
+
`Build it through buildIntelligenceProvider() (which installs the host-wide spawn cap + circuit breaker), ` +
|
|
124
|
+
`or add an allowlist entry here with a spawn-bounding justification.`,
|
|
125
|
+
);
|
|
126
|
+
violations++;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
if (violations > 0) {
|
|
133
|
+
console.error(`\nlint-no-unbounded-llm-spawn: ${violations} violation(s). ` +
|
|
134
|
+
`See docs/specs/forkbomb-prevention-simple.md (§P1 — every spawn-capable provider must ride the spawn-cap funnel).`);
|
|
135
|
+
process.exit(1);
|
|
136
|
+
}
|
|
137
|
+
console.log('lint-no-unbounded-llm-spawn: clean');
|