@nexus-cortex/server 4.124.31 → 4.124.33

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.
@@ -0,0 +1,409 @@
1
+ #!/bin/sh
2
+ # Canonical workspace inventory (CORTEX_INVENTORY=1, dark, 2026-09-29). Vendored by prepack to <pkg>/.cortex/inventory beside the orient
3
+ # scaffold. ONE mechanical, read-only picture of the task workspace that feeds BOTH the action model (orient prints it) and the steering models
4
+ # (the lift planner / EndTurn judge environment report). Evidence (r-orient-deficiencies-2026-09-29, r-steering-input-truncation-2026-09-29):
5
+ # flaky MiMo / TB4.0 / TB2.1 pairs diverge in the first 30 actions on workspace knowledge — the checker or contract not surfaced, a deep or
6
+ # out-of-workdir asset never shown (the lift plan names an asset only when orient showed it: TB4 0/6 vs 4/4), a listed file whose ROLE was not
7
+ # understood (a raw weights blob, a comma-decimal data file, a .dat that is a ZIP), the site-packages copy shadowing the workspace copy, a
8
+ # declared dependency silently missing.
9
+ # RULES: read-only (writes nothing, anywhere); no secrets (the task's own env comes from /proc/1/environ, harness vars and anything named
10
+ # *KEY*/*TOKEN*/*SECRET*/*PASSWORD* are dropped/redacted — transcripts are banked); priority sections are never capped; every capped section
11
+ # ends with "… N more … — <exact command>" so nothing is silently truncated. Always exits 0.
12
+ W="${1:-$(pwd)}"
13
+ cd "$W" 2>/dev/null || { echo "== WORKSPACE INVENTORY: $W (not accessible) =="; exit 0; }
14
+ PY=$(command -v python3 2>/dev/null || command -v python 2>/dev/null)
15
+ if [ -z "$PY" ]; then
16
+ # No interpreter: the shell-only inventory (structure + roles by name + env + services). Still no silent truncation.
17
+ echo "== WORKSPACE INVENTORY: $W (shell-only: no python on this box) =="
18
+ PRUNE='( -name .git -o -name node_modules -o -name __pycache__ -o -name .venv -o -name venv -o -name .cortex -o -name .cache ) -prune -o'
19
+ # shellcheck disable=SC2086
20
+ N=$(find . $PRUNE -type f -print 2>/dev/null | wc -l | tr -d ' ')
21
+ echo "files: $N (excluding .git node_modules __pycache__ venvs .cortex .cache)"
22
+ echo "-- directories (file counts) --"
23
+ # shellcheck disable=SC2086
24
+ find . -maxdepth 3 $PRUNE -type d -print 2>/dev/null | sed 's#^\./##' | grep -v '^\.$' | sort | head -60 | while read -r d; do
25
+ printf ' %s/ (%s)\n' "$d" "$(find "$d" -maxdepth 1 -type f 2>/dev/null | wc -l | tr -d ' ')"; done
26
+ echo "-- files at depth <= 3 --"
27
+ # shellcheck disable=SC2086
28
+ L=$(find . -maxdepth 3 $PRUNE -type f -print 2>/dev/null | sed 's#^\./##' | sort)
29
+ C=$(printf '%s\n' "$L" | grep -c . )
30
+ printf '%s\n' "$L" | head -150 | sed 's/^/ /'
31
+ [ "$C" -gt 150 ] && echo " … $((C-150)) more files at depth <= 3 not shown — list all: find . -type f -not -path './.git/*'"
32
+ for d in /shared /data /mnt /srv /workspace /input /inputs /output /outputs; do
33
+ [ -d "$d" ] && [ "$d" != "$W" ] && [ -n "$(ls -A "$d" 2>/dev/null)" ] && echo "-- outside the workdir: $d ($(find "$d" -maxdepth 4 -type f 2>/dev/null | head -2000 | wc -l | tr -d ' ') files, first 2000 / depth 4 counted) — list: find $d -type f"
34
+ done
35
+ exit 0
36
+ fi
37
+ exec "$PY" - "$W" <<'PYINV'
38
+ import ast, json, os, re, subprocess, sys
39
+
40
+ W = os.path.abspath(sys.argv[1])
41
+ SKIP_DIRS = {'.git', 'node_modules', '__pycache__', '.venv', 'venv', '.cortex', '.cache', '.pytest_cache', '.mypy_cache', '.tox', '.npm',
42
+ '.gradle', '.m2', 'site-packages', 'dist-packages', '.idea', '.vscode', '.addon-tools'}
43
+ MAX_WALK = 60000
44
+ # Output is bucketed per section and emitted DECISIVE-FIRST (2026-09-29): the model reads orient through `| head -50/-100` in ~93% of sessions
45
+ # (504/541, .bench/mimo/boot-prompt-audit.py) and cut the inventory in 8/17 cw sessions — so what decides a task (how it is checked, which
46
+ # copy of the code runs, missing deps, services, data outside the workdir) comes before the long per-file listing. Computation order is unchanged.
47
+ SECTIONS, CUR = {}, ['header']
48
+ EMIT = ['header', 'checked', 'python', 'node', 'services', 'outside', 'structure', 'files', 'env']
49
+
50
+
51
+ def sec(name):
52
+ CUR[0] = name
53
+
54
+
55
+ def p(line):
56
+ SECTIONS.setdefault(CUR[0], []).append(line)
57
+
58
+
59
+ def rel(x):
60
+ return os.path.relpath(x, W)
61
+
62
+
63
+ def more(n, what, cmd):
64
+ return f' … {n} more {what} not shown — {cmd}'
65
+
66
+
67
+ # ---------------------------------------------------------------- walk (bounded; never follows symlinked dirs)
68
+ files, dirs = [], {}
69
+ walked = 0
70
+ truncated_walk = False
71
+ for dp, dns, fns in os.walk(W, topdown=True, followlinks=False):
72
+ dns[:] = sorted(d for d in dns if d not in SKIP_DIRS and not d.endswith('.egg-info'))
73
+ r = rel(dp)
74
+ dirs[r] = len(fns)
75
+ for f in sorted(fns):
76
+ fp = os.path.join(dp, f)
77
+ try:
78
+ st = os.lstat(fp)
79
+ except OSError:
80
+ continue
81
+ files.append((rel(fp), st.st_size))
82
+ walked += 1
83
+ if walked >= MAX_WALK:
84
+ truncated_walk = True
85
+ break
86
+ if truncated_walk:
87
+ break
88
+
89
+ # ---------------------------------------------------------------- role classification + peeks
90
+ SCRIPT = re.compile(r'\.(py|sh|bash|js|mjs|cjs|ts|tsx|rb|pl|go|rs|c|cc|cpp|h|hpp|java|kt|r|jl|lua|php|swift|scala|m)$', re.I)
91
+ DOC = re.compile(r'\.(md|rst|txt|adoc|pdf|html?|docx?|odt)$', re.I)
92
+ DATA = re.compile(r'\.(csv|tsv|jsonl|ndjson|json|parquet|feather|arrow|npy|npz|pkl|pickle|h5|hdf5|db|sqlite3?|xlsx?|xml|ya?ml|toml|ini|cfg|'
93
+ r'dat|bin|raw|gz|zip|tar|tgz|bz2|xz|7z|fa|fasta|fastq|bam|sam|vcf|bed|gff3?|pdb|cif|wav|mp3|flac|png|jpe?g|gif|bmp|tiff?|svg|'
94
+ r'stl|step|stp|obj|ply|glb|gltf|ckpt|pt|pth|safetensors|onnx|gguf|mat|nc|log|ttf|otf|woff2?)$', re.I)
95
+ CHECKER = re.compile(r'(check|verif|validat|grade|grader|probe|evaluat|eval|scor|judge|assert|audit|regression|smoke|harness|contract_runner|'
96
+ r'run_tests?|run_[a-z0-9_-]+|workflow|diagnos|benchmark|bench)[^/]*\.(py|sh|js|ts|mjs)$', re.I)
97
+ CONTRACT = re.compile(r'(contract|schema|spec|expected|golden|reference|cases|fixture|sample_output|example_output|output_format|interface|'
98
+ r'requirements?_spec|acceptance)[^/]*\.(json|ya?ml|toml|md|txt|csv|jsonl)$|(^|/)(CONTRACT|SPEC|REPAIR_CONTRACT|'
99
+ r'ACCEPTANCE)[^/]*$', re.I)
100
+ TESTF = re.compile(r'(^|/)(tests?|spec|__tests__)/|(^|/)test_[^/]+$|_test\.[a-z]+$|\.test\.[a-z]+$|\.spec\.[a-z]+$', re.I)
101
+ MANIFEST = re.compile(r'(^|/)(requirements[^/]*\.txt|pyproject\.toml|setup\.py|setup\.cfg|Pipfile|environment\.ya?ml|package\.json|Cargo\.toml|'
102
+ r'go\.mod|Gemfile|pom\.xml|build\.gradle|CMakeLists\.txt|Makefile|Dockerfile|docker-compose[^/]*\.ya?ml|tox\.ini|pytest\.ini|'
103
+ r'conftest\.py|\.env\.example)$', re.I)
104
+ VENDOR = re.compile(r'(^|/)(vendor|third_party|external|deps|_offline_deps|offline_deps|runtime_compat|wheels)/', re.I)
105
+
106
+
107
+ def role(path):
108
+ if CHECKER.search(path) and not TESTF.search(path): return 'checker/runner'
109
+ if CONTRACT.search(path): return 'contract/spec'
110
+ if MANIFEST.search(path): return 'manifest/config'
111
+ if TESTF.search(path): return 'test'
112
+ if SCRIPT.search(path): return 'source'
113
+ if DOC.search(path) or re.search(r'(^|/)(README|NOTES|INSTRUCTIONS|TODO|CHANGELOG|LICENSE)[^/]*$', path, re.I): return 'doc'
114
+ if DATA.search(path): return 'data'
115
+ return 'other'
116
+
117
+
118
+ def head_bytes(path, n=4096):
119
+ try:
120
+ with open(os.path.join(W, path), 'rb') as fh:
121
+ return fh.read(n)
122
+ except OSError:
123
+ return b''
124
+
125
+
126
+ MAGIC = [(b'PK\x03\x04', 'zip archive'), (b'\x1f\x8b', 'gzip'), (b'BZh', 'bzip2'), (b'\xfd7zXZ', 'xz'), (b'7z\xbc\xaf', '7z'),
127
+ (b'\x89PNG', 'png image'), (b'\xff\xd8\xff', 'jpeg image'), (b'GIF8', 'gif image'), (b'%PDF', 'pdf'), (b'SQLite format 3', 'sqlite db'),
128
+ (b'\x7fELF', 'ELF binary'), (b'\x93NUMPY', 'numpy array'), (b'\x80\x02', 'pickle'), (b'\x80\x04', 'pickle'), (b'\x80\x05', 'pickle'),
129
+ (b'RIFF', 'riff (wav/avi)'), (b'ustar', 'tar')]
130
+
131
+
132
+ def human(n):
133
+ for u in ('B', 'KB', 'MB', 'GB'):
134
+ if n < 1024 or u == 'GB':
135
+ return f'{n:.0f}{u}' if u == 'B' else f'{n:.1f}{u}'
136
+ n /= 1024
137
+
138
+
139
+ def peek(path, size, rl):
140
+ b = head_bytes(path)
141
+ if not b:
142
+ return 'empty' if size == 0 else ''
143
+ for sig, name in MAGIC:
144
+ if b.startswith(sig) or (sig == b'ustar' and b[257:262] == b'ustar'):
145
+ ext = os.path.splitext(path)[1].lower()
146
+ expect = {'.zip': 'zip', '.gz': 'gzip', '.png': 'png', '.jpg': 'jpeg', '.jpeg': 'jpeg', '.pdf': 'pdf', '.db': 'sqlite',
147
+ '.sqlite': 'sqlite', '.npy': 'numpy', '.pkl': 'pickle', '.tar': 'tar', '.xz': 'xz', '.bz2': 'bzip2', '.wav': 'riff'}
148
+ mism = ext and ext in expect and expect[ext] not in name
149
+ unexpected = ext and ext not in expect and name not in ('ELF binary',)
150
+ tag = name + (f' (NOTE: content is {name}, not what "{ext}" suggests)' if (mism or unexpected) else '')
151
+ return tag
152
+ try:
153
+ t = b.decode('utf-8')
154
+ except UnicodeDecodeError:
155
+ nz = sum(1 for c in b[:512] if c == 0)
156
+ return f'binary ({nz} NUL bytes in first 512; e.g. raw array / weights / packed data)'
157
+ lines = t.splitlines()
158
+ if rl == 'data' or re.search(r'\.(csv|tsv|dat|txt)$', path, re.I):
159
+ first = next((l for l in lines if l.strip()), '')[:160]
160
+ body = [l for l in lines[:12] if l.strip()][1:6]
161
+ note = ''
162
+ if any(re.search(r'\d,\d', l) and ';' in l for l in body): note = ' (NOTE: ";"-separated with comma decimals, e.g. ' + body[0][:40] + ')'
163
+ elif any(re.match(r'^\s*-?\d+,\d+[\s\t]+-?\d+,\d+', l) for l in body): note = ' (NOTE: comma decimals, e.g. ' + body[0][:40] + ')'
164
+ if path.lower().endswith(('.json',)) or first.lstrip().startswith(('{', '[')):
165
+ try:
166
+ with open(os.path.join(W, path), encoding='utf-8') as fh:
167
+ obj = json.load(fh) if size < 2_000_000 else None
168
+ if isinstance(obj, dict): return 'json object, keys: ' + ', '.join(list(obj)[:14]) + (' …' if len(obj) > 14 else '')
169
+ if isinstance(obj, list): return f'json array[{len(obj)}]' + (', item keys: ' + ', '.join(list(obj[0])[:12]) if obj and isinstance(obj[0], dict) else '')
170
+ except Exception:
171
+ pass
172
+ return f'first line: {first}{note}' if first else 'text'
173
+ if rl in ('source', 'checker/runner', 'test'):
174
+ if path.endswith('.py'):
175
+ try:
176
+ src = open(os.path.join(W, path), encoding='utf-8', errors='replace').read() if size < 2_000_000 else t
177
+ tree = ast.parse(src)
178
+ defs = [n.name for n in tree.body if isinstance(n, (ast.FunctionDef, ast.AsyncFunctionDef, ast.ClassDef))]
179
+ main = '__main__' in src
180
+ return (('defines: ' + ', '.join(defs[:10]) + (' …' if len(defs) > 10 else '')) if defs else 'no top-level defs') + \
181
+ (' | runnable (__main__)' if main else '') + f' | {src.count(chr(10))} lines'
182
+ except Exception:
183
+ pass
184
+ defs = re.findall(r'^(?:export\s+)?(?:async\s+)?(?:function|class|def|fn|func|interface|struct)\s+([A-Za-z_][\w]*)', t, re.M)
185
+ return ('defines: ' + ', '.join(defs[:10]) if defs else f'{len(lines)}+ lines')
186
+ if rl == 'doc':
187
+ first = next((l.strip('# ').strip() for l in lines if l.strip()), '')
188
+ return f'"{first[:120]}"'
189
+ return ''
190
+
191
+
192
+ classified = [(f, s, role(f)) for f, s in files]
193
+ by_role = {}
194
+ for f, s, r in classified:
195
+ by_role.setdefault(r, []).append((f, s))
196
+
197
+ # ---------------------------------------------------------------- header
198
+ p(f'== WORKSPACE INVENTORY: {W} ==')
199
+ p(f'{len(files)} files in {len(dirs)} dirs (excluded: ' + ', '.join(sorted(SKIP_DIRS)[:8]) + ' …)' +
200
+ (f' — WALK STOPPED at {MAX_WALK} files; the rest is not listed — find . -type f | wc -l' if truncated_walk else ''))
201
+ counts = ', '.join(f'{r} {len(v)}' for r, v in sorted(by_role.items(), key=lambda kv: -len(kv[1])))
202
+ p('by role: ' + counts)
203
+
204
+ # ---------------------------------------------------------------- 1. verification + contracts (PRIORITY — never capped)
205
+ sec('checked')
206
+ chk = by_role.get('checker/runner', []); con = by_role.get('contract/spec', [])
207
+ if chk or con:
208
+ p('-- HOW THIS TASK IS CHECKED (task-shipped checkers/runners and contracts — read these before building) --')
209
+ for f, s in chk:
210
+ src = head_bytes(f, 200_000).decode('utf-8', 'replace')
211
+ usage = next((l.strip() for l in src.splitlines() if re.search(r'usage|^ *Run:|add_argument|sys\.argv|getopts', l, re.I)), '')
212
+ writes = sorted(set(re.findall(r'["\']([\w./-]+\.(?:json|jsonl|csv|txt|md|yaml|yml|html|png))["\']', src)))[:6]
213
+ consts = sorted(set(re.findall(r'["\']?(schema[_-]?version|SCHEMA[_A-Z]*|output_schema[_a-z]*)["\']?\s*[:=]\s*["\']?([\w.:-]+)', src)))[:4]
214
+ line = f' [checker] {f} ({human(s)})'
215
+ if VENDOR.search(f): line += ' — inside a vendored project'
216
+ p(line)
217
+ if usage: p(f' usage: {usage[:160]}')
218
+ if writes: p(' references: ' + ', '.join(writes))
219
+ if consts: p(' constants: ' + ', '.join(f'{a}={b}' for a, b in consts))
220
+ for f, s in con:
221
+ p(f' [contract] {f} ({human(s)}) — {peek(f, s, "data" if not f.lower().endswith(".md") else "doc")}'[:260])
222
+ tests = sorted({os.path.dirname(f) for f, _ in by_role.get('test', []) if os.path.dirname(f)})
223
+ if tests:
224
+ shown = tests[:12]
225
+ p(' test dirs: ' + ', '.join(shown) + (f' (+{len(tests)-12} more — find . -type d -name "test*")' if len(tests) > 12 else ''))
226
+
227
+ # ---------------------------------------------------------------- 2. structure: every dir with counts (capped with marker)
228
+ sec('structure')
229
+ p('-- STRUCTURE (dir: files directly inside) --')
230
+ dl = sorted(d for d in dirs if d != '.')
231
+ top = [d for d in dl if d.count('/') <= 1]
232
+ for d in top[:60]:
233
+ sub = sum(1 for x in dl if x.startswith(d + '/'))
234
+ p(f' {d}/ ({dirs[d]} files' + (f', {sub} subdirs' if sub else '') + ')')
235
+ if len(top) > 60:
236
+ p(more(len(top) - 60, 'directories at depth <= 2', 'find . -maxdepth 2 -type d'))
237
+ deep = [d for d in dl if d.count('/') > 1]
238
+ if deep:
239
+ p(f' ({len(deep)} deeper directories — find . -mindepth 3 -type d)')
240
+
241
+ # ---------------------------------------------------------------- 3. files by role with a peek (priority roles in full, bulk capped)
242
+ sec('files')
243
+ CAPS = {'source': 40, 'doc': 30, 'data': 40, 'manifest/config': 30, 'test': 20, 'other': 20}
244
+ ORDER = ['doc', 'manifest/config', 'source', 'data', 'test', 'other']
245
+ for r in ORDER:
246
+ items = by_role.get(r, [])
247
+ if not items: continue
248
+ # task files before vendored ones; shallow before deep
249
+ items = sorted(items, key=lambda x: (bool(VENDOR.search(x[0])), x[0].count('/'), x[0]))
250
+ cap = CAPS[r]
251
+ p(f'-- {r.upper()} ({len(items)}) --')
252
+ for f, s in items[:cap]:
253
+ pk = peek(f, s, r) if r in ('doc', 'data', 'source', 'other', 'manifest/config') else ''
254
+ p(f' {f} ({human(s)})' + (f' — {pk}' if pk else ''))
255
+ if len(items) > cap:
256
+ vend = sum(1 for f, _ in items[cap:] if VENDOR.search(f))
257
+ p(more(len(items) - cap, f'{r} files' + (f' ({vend} in vendored trees)' if vend else ''),
258
+ f'list: find . -type f | grep -v -e .git/ -e node_modules (role here = {r})'))
259
+
260
+ # ---------------------------------------------------------------- 4. python: which interpreter, which copy of the code runs, missing deps
261
+ sec('python')
262
+ def run(cmd, timeout=20):
263
+ try:
264
+ r = subprocess.run(cmd, capture_output=True, text=True, timeout=timeout, cwd=W)
265
+ return (r.stdout or '') + (r.stderr or '')
266
+ except Exception as e:
267
+ return ''
268
+
269
+
270
+ p('-- PYTHON --')
271
+ p(f' interpreter: {sys.executable} ({sys.version.split()[0]})' + (f' | VIRTUAL_ENV={os.environ.get("VIRTUAL_ENV")}' if os.environ.get('VIRTUAL_ENV') else ''))
272
+ pkgs = []
273
+ for d in sorted(dirs):
274
+ parts = d.split('/')
275
+ if d == '.' or len(parts) > 4: continue
276
+ if os.path.isfile(os.path.join(W, d, '__init__.py')) and not os.path.isfile(os.path.join(W, os.path.dirname(d) or '.', '__init__.py')):
277
+ pkgs.append(d)
278
+ pkgs = [x for x in pkgs if not TESTF.search(x + '/')][:12]
279
+ for d in pkgs:
280
+ name = os.path.basename(d); parent = os.path.dirname(d) or '.'
281
+ res = run([sys.executable, '-c', f'import {name},os;print(os.path.abspath({name}.__file__))'], 20).strip().splitlines()
282
+ where = res[-1] if res else ''
283
+ ws_copy = os.path.join(W, d)
284
+ if where.startswith(ws_copy):
285
+ p(f' import {name} → the workspace copy ({d}/)')
286
+ elif where.startswith('/'):
287
+ p(f' import {name} → {where} ⚠ NOT the workspace copy ({d}/) — run with PYTHONPATH={os.path.join(W, parent)} to use/test the workspace code')
288
+ else:
289
+ err = next((l for l in res if 'Error' in l), 'fails')
290
+ p(f' import {name} (workspace {d}/) → {err[:120]} from {W}; with PYTHONPATH={os.path.join(W, parent)} it resolves to the workspace copy')
291
+ extra = sorted(d for d in dirs if re.search(r'(^|/)(_?offline_deps|runtime_compat|wheels|vendor_deps)$', d, re.I))[:6]
292
+ if extra:
293
+ p(' dependency dirs shipped with the task: ' + ', '.join(extra) + ' (add to PYTHONPATH / pip install --no-index --find-links as appropriate)')
294
+ # declared vs installed
295
+ declared = []
296
+ for f, _ in by_role.get('manifest/config', []):
297
+ if VENDOR.search(f) and f.count('/') > 2: continue
298
+ b = os.path.basename(f).lower()
299
+ try:
300
+ txt = open(os.path.join(W, f), encoding='utf-8', errors='replace').read()
301
+ except OSError:
302
+ continue
303
+ if b.startswith('requirements') and b.endswith('.txt'):
304
+ declared += [(re.split(r'[<>=!~\[; ]', l.strip())[0], f) for l in txt.splitlines() if l.strip() and not l.strip().startswith(('#', '-'))]
305
+ elif b == 'pyproject.toml':
306
+ m = re.search(r'dependencies\s*=\s*\[(.*?)\]', txt, re.S)
307
+ if m: declared += [(re.split(r'[<>=!~\[; ]', x.strip().strip('"\''))[0], f) for x in m.group(1).split(',') if x.strip().strip('"\'')]
308
+ missing = []
309
+ if declared:
310
+ try:
311
+ from importlib import metadata as md
312
+ have = {re.sub(r'[-_.]+', '-', (d.metadata['Name'] or '').lower()) for d in md.distributions()}
313
+ except Exception:
314
+ have = set()
315
+ for name, src in declared:
316
+ if name and re.sub(r'[-_.]+', '-', name.lower()) not in have:
317
+ missing.append(f'{name} ({src})')
318
+ missing = sorted(set(missing))
319
+ if missing:
320
+ p(' declared but NOT installed: ' + ', '.join(missing[:30]) + (f' … +{len(missing)-30} more' if len(missing) > 30 else ''))
321
+ else:
322
+ p(f' all {len(declared)} declared python dependencies are installed')
323
+
324
+ # ---------------------------------------------------------------- 5. node
325
+ sec('node')
326
+ pj = [f for f, _ in by_role.get('manifest/config', []) if os.path.basename(f) == 'package.json' and f.count('/') <= 2 and 'node_modules' not in f]
327
+ for f in pj[:3]:
328
+ try:
329
+ o = json.load(open(os.path.join(W, f)))
330
+ except Exception:
331
+ continue
332
+ deps = list((o.get('dependencies') or {})) + list((o.get('devDependencies') or {}))
333
+ nm = os.path.join(W, os.path.dirname(f), 'node_modules')
334
+ miss = [d for d in deps if not os.path.isdir(os.path.join(nm, d))]
335
+ scripts = list((o.get('scripts') or {}))
336
+ p(f'-- NODE {f}: scripts: ' + (', '.join(scripts[:12]) or 'none') + f' | {len(deps)} deps' +
337
+ (f', NOT installed: {", ".join(miss[:20])}' + (' …' if len(miss) > 20 else '') if miss else (', node_modules present' if os.path.isdir(nm) else ', no node_modules')))
338
+
339
+ # ---------------------------------------------------------------- 6. task environment (from the container's own init env; secrets redacted)
340
+ sec('env')
341
+ BOILER = {'PATH', 'HOME', 'HOSTNAME', 'TERM', 'SHLVL', 'PWD', 'OLDPWD', '_', 'LANG', 'LC_ALL', 'DEBIAN_FRONTEND', 'container', 'GPG_KEY',
342
+ 'PYTHON_VERSION', 'PYTHON_SHA256', 'PYTHON_PIP_VERSION', 'PYTHON_GET_PIP_URL', 'PYTHON_GET_PIP_SHA256', 'PYTHON_SETUPTOOLS_VERSION',
343
+ 'NODE_VERSION', 'YARN_VERSION', 'LS_COLORS', 'SSL_CERT_DIR', 'SSL_CERT_FILE', 'NVIDIA_VISIBLE_DEVICES', 'NVIDIA_DRIVER_CAPABILITIES'}
344
+ HARNESS = re.compile(r'^(CORTEX_|TB2_|MENTORSHIP_|HELPER_|VISION_|NEXUS_|OMNI|ANTHROPIC|OPENAI|DEEPSEEK|XAI|GROQ|GEMINI|GOOGLE_API|MISTRAL|'
345
+ r'TYPESAFE|HF_|HUGGING|MODEL_|DEFAULT_MODEL|MAX_TOOL|TOOL_TIMEOUT|ENABLE_WEBTOOLS|CANON_|NODE_OPTIONS|NPM_|BENCH_|HARBOR)')
346
+ SECRET = re.compile(r'(KEY|TOKEN|SECRET|PASSWORD|PASSWD|CREDENTIAL|AUTH|COOKIE|SESSION)', re.I)
347
+ env = {}
348
+ try:
349
+ raw = open('/proc/1/environ', 'rb').read().split(b'\0')
350
+ for kv in raw:
351
+ if b'=' in kv:
352
+ k, v = kv.split(b'=', 1); env[k.decode('utf-8', 'replace')] = v.decode('utf-8', 'replace')
353
+ src_note = 'from the container init process'
354
+ except Exception:
355
+ src_note = None
356
+ if src_note is not None:
357
+ keep = []
358
+ for k in sorted(env):
359
+ if k in BOILER or HARNESS.search(k): continue
360
+ v = env[k]
361
+ if SECRET.search(k): v = '<redacted>'
362
+ keep.append(f'{k}={v[:120]}')
363
+ if keep:
364
+ p(f'-- TASK ENVIRONMENT ({src_note}; boilerplate and harness variables omitted, secrets redacted) --')
365
+ for kv in keep[:40]: p(' ' + kv)
366
+ if len(keep) > 40: p(more(len(keep) - 40, 'variables', 'cat /proc/1/environ | tr "\\0" "\\n"'))
367
+
368
+ # ---------------------------------------------------------------- 7. services + paths outside the workdir
369
+ sec('services')
370
+ hosts = []
371
+ try:
372
+ for l in open('/etc/hosts'):
373
+ parts = l.split()
374
+ if len(parts) >= 2 and not parts[0].startswith(('#', '127.', '::1', 'fe00', 'ff0')):
375
+ hosts += [h for h in parts[1:] if not re.match(r'^[0-9a-f]{12}$', h) and h not in ('localhost',)]
376
+ except OSError:
377
+ pass
378
+ ports = []
379
+ for f in ('/proc/net/tcp', '/proc/net/tcp6'):
380
+ try:
381
+ for l in open(f).read().splitlines()[1:]:
382
+ x = l.split()
383
+ if len(x) > 3 and x[3] == '0A':
384
+ ports.append(int(x[1].split(':')[1], 16))
385
+ except OSError:
386
+ pass
387
+ urlvars = [f'{k}={env[k][:80]}' for k in sorted(env) if re.search(r'(HOST|PORT|URL|URI|ENDPOINT|ADDR)', k) and not HARNESS.search(k) and not SECRET.search(k)]
388
+ if hosts or ports or urlvars:
389
+ p('-- SERVICES --')
390
+ if hosts: p(' other hosts on this network: ' + ', '.join(sorted(set(hosts))[:20]))
391
+ if ports: p(' listening locally: ' + ', '.join(str(x) for x in sorted(set(ports))[:20]))
392
+ for u in urlvars[:12]: p(' ' + u)
393
+ sec('outside')
394
+ outside = []
395
+ for d in ('/shared', '/data', '/mnt', '/srv', '/workspace', '/input', '/inputs', '/output', '/outputs', '/reference', '/resources', '/task', '/opt/task'):
396
+ if os.path.isdir(d) and not W.startswith(d) and not d.startswith(W):
397
+ n, capped = 0, False
398
+ try:
399
+ for dp, dns, fs in os.walk(d, followlinks=False): # bounded: a large mount must never stall the inventory
400
+ n += len(fs)
401
+ if n >= 2000 or dp.count('/') - d.count('/') >= 4:
402
+ capped = True; break
403
+ except Exception:
404
+ pass
405
+ if n: outside.append(f'{d} ({n}{"+" if capped else ""} files)')
406
+ if outside:
407
+ p('-- OUTSIDE THE WORKDIR (task data may live here) -- ' + ', '.join(outside) + ' — list: find <dir> -type f | head -100')
408
+ print('\n'.join(line for name in EMIT for line in SECTIONS.get(name, [])))
409
+ PYINV
package/.cortex/orient CHANGED
@@ -5,13 +5,37 @@
5
5
  # has no .cortex/orient of its own. Deterministic, read-only except for one
6
6
  # mechanical .cortex/CORTEX.md render (never overwrites), always exits 0.
7
7
  W="$(pwd)"
8
+ # Clean workspace (CORTEX_WORKSPACE_CLEAN=1, dark, 2026-09-29): orient writes nothing into the task's tree. The mechanical CORTEX.md and the
9
+ # baseline go to the harness state dir ($CORTEX_STATE_DIR, else ~/.cortex/projects/<sha1(path)[:12]>, else /tmp/nexus-cortex/<same>, the
10
+ # same order and key as the harness's resolveCortexStateDir). Graders that list the directory or diff the repo (TB2.1 sanitize-git-repo,
11
+ # polyglot listdir == [one file]) see only the model's work. Unset = unchanged.
12
+ CX="$W/.cortex"; CLEAN=0
13
+ case "${CORTEX_WORKSPACE_CLEAN:-0}" in 1|true|TRUE|True|on|ON) CLEAN=1;; esac
14
+ if [ "$CLEAN" = "1" ]; then
15
+ if [ -n "${CORTEX_STATE_DIR:-}" ] && mkdir -p "$CORTEX_STATE_DIR" 2>/dev/null && [ -w "$CORTEX_STATE_DIR" ]; then CX="$CORTEX_STATE_DIR"
16
+ else
17
+ H=$(printf %s "$W" | sha1sum 2>/dev/null | cut -c1-12); [ -n "$H" ] || H=$(printf %s "$W" | cksum | cut -d' ' -f1)
18
+ CX="${HOME:-/tmp}/.cortex/projects/$H"; mkdir -p "$CX" 2>/dev/null && [ -w "$CX" ] || { CX="${TMPDIR:-/tmp}/nexus-cortex/$H"; mkdir -p "$CX" 2>/dev/null; }
19
+ fi
20
+ fi
21
+ # Canonical workspace inventory (CORTEX_INVENTORY=1, dark, 2026-09-29): the full role-labelled inventory (checkers + contracts, every dir,
22
+ # files with a content peek, which copy of the code imports, missing deps, task env, services, data outside the workdir) replaces the
23
+ # workspace map and the v2 verification section; the tooling / git / baseline / setup lines below still print. Unset = unchanged output.
24
+ INV=""; if [ "${CORTEX_INVENTORY:-0}" = "1" ]; then for c in "$(dirname "$0")/inventory" "${CORTEX_ROOT:-/nonexistent}/.cortex/inventory"; do [ -f "$c" ] && { INV="$c"; break; }; done; fi
25
+ INV_OUT=""
26
+ if [ -n "$INV" ]; then
27
+ # Captured here, PRINTED after the setup line below (2026-09-29): the model reads orient through `| head -50/-100` in ~93% of sessions,
28
+ # and with the inventory first 8/17 cw sessions lost orient's own short lines (git, the `-- baseline:` revert instruction, setup).
29
+ INV_OUT=$(sh "$INV" "$W" 2>/dev/null)
30
+ else
8
31
  echo "== WORKSPACE MAP: $W =="
9
32
  ls -1A "$W" 2>/dev/null | head -40
33
+ fi
10
34
  # orient v2 ships DARK (2026-09-27): every v2 section runs only with CORTEX_ORIENT_V2=1; unset = the v1 output byte-for-byte.
11
35
  V2="${CORTEX_ORIENT_V2:-0}"
12
36
  # orient v2 (2026-09-27, MiMo: the whole library lived under vendor/ and the map showed one level): one more level for the top
13
37
  # directories (skipping caches/vendored deps of the toolchain), capped so the map stays small.
14
- [ "$V2" = "1" ] && for d in $(ls -1A "$W" 2>/dev/null | head -40); do
38
+ [ "$V2" = "1" ] && [ -z "$INV" ] && for d in $(ls -1A "$W" 2>/dev/null | head -40); do
15
39
  [ -d "$W/$d" ] || continue
16
40
  case "$d" in .git|node_modules|__pycache__|.venv|venv|.cache|.cortex|.addon-tools|dist|build|target) continue;; esac
17
41
  n=$(ls -1A "$W/$d" 2>/dev/null | wc -l | tr -d ' ')
@@ -64,7 +88,7 @@ fi
64
88
  # protected-file guard (a file outside the task's repair set was modified, usually vendored library code) and the workspaces are not git
65
89
  # repos, so nothing could show the agent what it had changed. Record a checksum list ONCE (never overwritten, so a re-run of orient keeps
66
90
  # the start state) and ship `.cortex/changed`, which lists modified / added / deleted files against it. POSIX cksum; capped.
67
- if [ "${CORTEX_ORIENT_BASELINE:-0}" = "1" ]; then
91
+ if [ "${CORTEX_ORIENT_BASELINE:-0}" = "1" ] && [ "$CLEAN" != "1" ]; then
68
92
  mkdir -p "$W/.cortex" 2>/dev/null
69
93
  cat > "$W/.cortex/changed" 2>/dev/null <<'CHANGED'
70
94
  #!/bin/sh
@@ -85,12 +109,13 @@ CHANGED
85
109
  fi
86
110
  BN=$(wc -l < "$W/.cortex/baseline.cksum" 2>/dev/null | tr -d ' ')
87
111
  echo "-- baseline: ${BN:-0} files recorded at start; \`sh .cortex/changed\` lists files you modified/added/deleted. Before finishing, run it and revert every change the task did not require."
88
- elif [ "${CORTEX_ORIENT_BASELINE:-0}" = "auto" ] && ! { command -v git >/dev/null 2>&1 && git -C "$W" rev-parse --is-inside-work-tree >/dev/null 2>&1; }; then
112
+ elif { [ "${CORTEX_ORIENT_BASELINE:-0}" = "1" ] && [ "$CLEAN" = "1" ]; } || { [ "${CORTEX_ORIENT_BASELINE:-0}" = "auto" ] && ! { command -v git >/dev/null 2>&1 && git -C "$W" rev-parse --is-inside-work-tree >/dev/null 2>&1; }; }; then
89
113
  # auto (general work, 2026-09-27): a git repo already has `git status`, so skip it; otherwise keep the baseline OUTSIDE the project
90
114
  # (the user's ~/.cortex, else /tmp), keyed by the workspace path, so nothing is written into the tree being worked on.
91
115
  KEY=$(printf %s "$W" | cksum | cut -d' ' -f1)
92
116
  BD="${HOME:-/tmp}/.cortex/baselines/$KEY"
93
117
  mkdir -p "$BD" 2>/dev/null && [ -w "$BD" ] || { BD="${TMPDIR:-/tmp}/cortex-baselines/$KEY"; mkdir -p "$BD" 2>/dev/null; }
118
+ [ "$CLEAN" = "1" ] && { BD="$CX/baseline"; mkdir -p "$BD" 2>/dev/null; }
94
119
  { printf '#!/bin/sh\n# Lists files modified / added / deleted in %s since orient recorded its start state.\nW=%s\nB=%s\n' "$W" "'$W'" "'$BD/baseline.cksum'"
95
120
  cat <<'CHANGED'
96
121
  cd "$W" || exit 0
@@ -108,7 +133,11 @@ CHANGED
108
133
  ( cd "$W" && find . \( -path ./.git -o -path ./.cortex -o -name node_modules -o -name __pycache__ -o -name .venv -o -name venv -o -name .cache -o -name .pytest_cache -o -name .mypy_cache \) -prune -o -type f -size -20M -print 2>/dev/null | head -20000 | tr '\n' '\0' | xargs -0 cksum 2>/dev/null > "$BD/baseline.cksum" )
109
134
  fi
110
135
  BN=$(wc -l < "$BD/baseline.cksum" 2>/dev/null | tr -d ' ')
136
+ if [ "$CLEAN" = "1" ] && [ "${CORTEX_ORIENT_BASELINE:-0}" = "1" ]; then
137
+ echo "-- baseline: ${BN:-0} files recorded at start; \`sh $BD/changed\` lists files you modified/added/deleted. Before finishing, run it and revert every change the task did not require."
138
+ else
111
139
  echo "-- baseline: ${BN:-0} files recorded at start (not a git repo); \`sh $BD/changed\` lists files you modified/added/deleted. Before finishing, run it and revert changes to existing files the task did not require."
140
+ fi
112
141
  fi
113
142
  # Bare-box hint (2026-09-03, operator-simplified): a task container may ship WITHOUT the language, compiler,
114
143
  # package or library the objective needs — on purpose (the agent phase is bare; internet is usually allowed).
@@ -122,7 +151,22 @@ if [ "${CORTEX_ORIENT_BOOTSTRAP:-0}" = "1" ] && { ! command -v python3 >/dev/nul
122
151
  PM=""; for m in apt-get apk dnf yum pacman zypper brew; do command -v "$m" >/dev/null 2>&1 && { PM="$m"; break; }; done
123
152
  ROOT=$([ "$(id -u 2>/dev/null)" = "0" ] && echo yes || echo no)
124
153
  GUARD=""; [ "$V2" = "1" ] && GUARD=" Install into the system or a venv, never into the task's own source or vendored tree."
154
+ # With the inventory on and a python interpreter present, the inventory has already checked the workspace manifests (requirements/
155
+ # pyproject/package.json) against what is installed. Replace the speculative "may be missing" paragraph with those facts
156
+ # (r-orient-deficiencies-2026-09-29 §3.3: "print only the MISSING ones … keep the generic line otherwise"); keep the install discipline
157
+ # (once, cached, never into the task's source/vendored tree). No manifest, no python, or no inventory = the generic line below, unchanged.
158
+ INV_MF=""; INV_MISS=""
159
+ if [ -n "$INV_OUT" ] && { command -v python3 >/dev/null 2>&1 || command -v python >/dev/null 2>&1; }; then
160
+ printf '%s\n' "$INV_OUT" | grep -qE "declared but NOT installed|declared python dependencies are installed|^-- NODE " && INV_MF=1
161
+ printf '%s\n' "$INV_OUT" | grep -qE "declared but NOT installed|^-- NODE .*NOT installed:" && INV_MISS=1
162
+ fi
163
+ if [ -n "$INV_MF" ] && [ -n "$INV_MISS" ]; then
164
+ echo "-- setup: the workspace manifests declare dependencies that are NOT installed (listed in the inventory below; pkg-mgr=${PM:-none}, root=$ROOT). Install what the task needs ONCE and reuse it, with a fast cached installer for the language (uv for Python, bun for JS) — do not re-download a large dependency twice.$GUARD Pin versions, then verify with a real run before finishing."
165
+ elif [ -n "$INV_MF" ]; then
166
+ echo "-- setup: the declared dependencies are installed (see the inventory below). If you still need a package, install it once$( [ "$V2" = "1" ] && echo " into the system or a venv, never into the task's own source or vendored tree" )."
167
+ else
125
168
  echo "-- setup: this box may be missing a tool/language/library the task needs (pkg-mgr=${PM:-none}, root=$ROOT). If so, INSTALL what you need yourself following standard practice (the system package manager, or the language's own installer); install ONCE and reuse it, and prefer a fast cached installer for the language (uv for Python, bun for JS) — do not re-download a large dependency twice.$GUARD Pin versions, then verify with a real run before finishing. An empty box is part of the task, not an error."
169
+ fi
126
170
  fi
127
171
  # orient v2 — VERIFICATION ENTRY POINTS: how this task's correctness is checked, so work is built and verified against the real
128
172
  # criteria, not the agent's own guess (MiMo K=3: in 57/79 failures the agent's own test passed on a wrong solution). Same usage-line
@@ -143,7 +187,9 @@ for f in pytest.ini tox.ini setup.cfg pyproject.toml Makefile package.json; do
143
187
  done
144
188
  TD=$(find . -maxdepth 3 -type d \( -name tests -o -name test \) 2>/dev/null | grep -vE "node_modules|/\.|site-packages" | head -4 | tr '\n' ' ')
145
189
  fi
146
- if [ -n "$VE$TC$TD" ]; then
190
+ # The inventory (captured above) prints AFTER orient's short facts — tooling, git, baseline, setup — so a `| head -N` read keeps them.
191
+ [ -n "$INV" ] && printf '%s\n' "$INV_OUT"
192
+ if [ -n "$VE$TC$TD" ] && [ -z "$INV" ]; then
147
193
  echo "== VERIFICATION ENTRY POINTS (build to and verify against these — not a test you invent) =="
148
194
  for f in $VE; do
149
195
  echo " $f"
@@ -196,28 +242,29 @@ machine_block() {
196
242
  ls -1A "$W" 2>/dev/null | head -25 | sed 's/^/- /'
197
243
  echo "$MB_END"
198
244
  }
199
- DOC=.cortex/CORTEX.md
245
+ DOC=.cortex/CORTEX.md; CD=.cortex
246
+ [ "$CLEAN" = "1" ] && { DOC="$CX/CORTEX.md"; CD="$CX"; }
200
247
  if [ ! -f "$DOC" ]; then
201
- mkdir -p .cortex 2>/dev/null
248
+ mkdir -p "$CD" 2>/dev/null
202
249
  {
203
250
  echo "# CORTEX.md (mechanical orient scan — refine with init_cortex_context)"
204
251
  echo
205
252
  machine_block
206
- } > "$DOC" 2>/dev/null && echo "(wrote mechanical .cortex/CORTEX.md)"
253
+ } > "$DOC" 2>/dev/null && echo "(wrote mechanical $DOC)"
207
254
  elif grep -q "orient:auto:begin" "$DOC" 2>/dev/null; then
208
- machine_block > .cortex/.orient-fresh-block 2>/dev/null
209
- awk '/orient:auto:begin/{f=1} f{print} /orient:auto:end/{f=0}' "$DOC" > .cortex/.orient-cur-block 2>/dev/null
210
- if cmp -s .cortex/.orient-cur-block .cortex/.orient-fresh-block; then
211
- rm -f .cortex/.orient-fresh-block .cortex/.orient-cur-block
255
+ machine_block > "$CD"/.orient-fresh-block 2>/dev/null
256
+ awk '/orient:auto:begin/{f=1} f{print} /orient:auto:end/{f=0}' "$DOC" > "$CD"/.orient-cur-block 2>/dev/null
257
+ if cmp -s "$CD"/.orient-cur-block "$CD"/.orient-fresh-block; then
258
+ rm -f "$CD"/.orient-fresh-block "$CD"/.orient-cur-block
212
259
  rm -f "$DOC.next" "$DOC.diff"
213
260
  echo "(CORTEX.md current)"
214
261
  else
215
- awk -v fresh=.cortex/.orient-fresh-block '
262
+ awk -v fresh="$CD/.orient-fresh-block" '
216
263
  /orient:auto:begin/ {skip=1; while ((getline line < fresh) > 0) print line; close(fresh); next}
217
264
  /orient:auto:end/ {skip=0; next}
218
265
  skip!=1 {print}' "$DOC" > "$DOC.next" 2>/dev/null
219
266
  diff -u "$DOC" "$DOC.next" > "$DOC.diff" 2>/dev/null
220
- rm -f .cortex/.orient-fresh-block .cortex/.orient-cur-block
267
+ rm -f "$CD"/.orient-fresh-block "$CD"/.orient-cur-block
221
268
  echo "(doctrine refresh staged for curation: machine sections drifted)"
222
269
  fi
223
270
  fi
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nexus-cortex/server",
3
- "version": "4.124.31",
3
+ "version": "4.124.33",
4
4
  "description": "Thin Express server wrapper for Nexus Cortex core library",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -20,8 +20,8 @@
20
20
  "prepack": "node ../../scripts/copy-pkg-cortex-scaffold.mjs"
21
21
  },
22
22
  "dependencies": {
23
- "@nexus-cortex/core": "4.124.31",
24
- "@nexus-cortex/executors": "4.124.31",
23
+ "@nexus-cortex/core": "4.124.33",
24
+ "@nexus-cortex/executors": "4.124.33",
25
25
  "chalk": "^5.3.0",
26
26
  "cors": "^2.8.5",
27
27
  "dotenv": "^16.4.5",