candor-ts 0.28.2 → 0.29.1

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/scan-core.mjs CHANGED
@@ -60,7 +60,13 @@ export const KAPPA_RULES = [
60
60
  // `receiveMessageOnPort` reads it. Covers `worker.postMessage`, `parentPort.postMessage`, and a
61
61
  // `MessagePort`'s `.postMessage` (all typed from this module). `new Worker(...)` spawns the thread but
62
62
  // construction is inert here (like the net-cluster ctors) — the message verbs are the IPC boundary.
63
- [/^(node:)?worker_threads$/, /^(postMessage|receiveMessageOnPort)$/, "Ipc"],
63
+ // …AND `postMessageToThread`, node 22's MODULE-LEVEL send. The name is anchored, so the newer API
64
+ // slipped past a rule that already covered every other spelling: `parentPort.postMessage`,
65
+ // `worker.postMessage`, a `MessagePort`'s `.postMessage` and `receiveMessageOnPort` were all Ipc while
66
+ // `postMessageToThread(id, value)` — the same channel, addressed by thread id — read PURE. Found by
67
+ // enumerating each builtin's EXPORTS and diffing them against what the table charges, rather than by
68
+ // testing the spellings someone already thought of.
69
+ [/^(node:)?worker_threads$/, /^(postMessage|postMessageToThread|receiveMessageOnPort)$/, "Ipc"],
64
70
  // node:cluster — `fork()` spawns a worker PROCESS and wires its IPC channel.
65
71
  [/^(node:)?cluster$/, /^fork$/, "Ipc"],
66
72
  // node:vm executes a runtime-supplied code STRING in-process — `runInThisContext`/`runInContext`/
@@ -162,7 +168,15 @@ export const KAPPA_RULES = [
162
168
  // node:os identity reads — userInfo (the OS user record) and hostname (the machine name) are
163
169
  // environment/host reads (Env), like System.getenv's host-identity cousins. The rest of node:os
164
170
  // (platform/arch/cpus/totalmem/…) is inert host introspection, left pure.
165
- [/^(node:)?os$/, /^(userInfo|hostname)$/, "Env"],
171
+ // …AND `tmpdir`/`homedir`, which this list read as pure until a cross-engine parity sweep asked why.
172
+ // They are not introspection: node resolves `homedir()` from `$HOME` and `tmpdir()` from
173
+ // `$TMPDIR`/`$TMP`/`$TEMP`, so they are ENVIRONMENT VARIABLE READS behind a convenience name — the
174
+ // rule this line already applies to `userInfo`/`hostname`, and the reason `platform`/`arch` stay out.
175
+ // candor-rust charges the identical operations (`std::env::temp_dir`, `env::var("HOME")`,
176
+ // `env::current_dir`) as Env, so ts was the outlier AND inconsistent with ITSELF: `os.hostname()` was
177
+ // Env while `os.homedir()` was pure. MEASURED 2026-08-18: `deny Env` answered exit 0 over
178
+ // `os.homedir()`. `platform`/`arch`/`cpus` are untouched — they read no variable.
179
+ [/^(node:)?os$/, /^(userInfo|hostname|tmpdir|homedir)$/, "Env"],
166
180
  [/^(argon2|bcrypt|bcryptjs)$/, null, "Rand"],
167
181
  // The ORM tier — VERB-PRECISE (the CLASSIFIER discipline: tag the execution boundary, not
168
182
  // builders; `createQueryBuilder` is pure, its `getMany`/`execute` is the I/O). Found on the