@stravica-ai/digital-operator-pa 0.1.38 → 0.1.39
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.
|
@@ -108,7 +108,7 @@ The failure mode is silent: launchd records exit code 78 (`EX_CONFIG`), the Stan
|
|
|
108
108
|
|
|
109
109
|
Proven live (w-2026-07-15-003, verified with `env -i`): cron's crond process provides a small fixed environment (`SHELL`, a narrow system `PATH` — `/usr/bin:/bin` — `HOME`, `LOGNAME`/`USER`), NOT a login shell's env. A schedule whose `command` relies on `pnpm`/`node` being on PATH via nvm silently fails to spawn once actually installed, even if it "worked" when tested from an interactive terminal.
|
|
110
110
|
|
|
111
|
-
The generated cron line handles this for you automatically: `scheduler install` detects `$HOME/.nvm/nvm.sh` on the target AT INSTALL TIME and, if present,
|
|
111
|
+
The generated cron line handles this for you automatically: `scheduler install` detects `$HOME/.nvm/nvm.sh` on the target AT INSTALL TIME and, if present, sources it inside the rendered chain. The generated cron line is `bash -c "{ date -u; . $HOME/.nvm/nvm.sh && cd <workDir> && <command>; } >> /tmp/<agent>-<id>.log 2>&1"` — the `{ ...; }` braces are load-bearing: without them the `>> log 2>&1` binds only to `<command>` and any earlier link failing (nvm-source, cd) sends its stderr to cron mail, which hosts with no MTA silently discard (w-2026-09-13-dave-042; 0.1.39 fix, smarthome01 crons fired but wrote no log 2026-09-09 -> 13). The leading `date -u` prints an ISO timestamp so a run that dies mid-chain still leaves dated evidence. If no nvm install is found, the preamble is simply omitted — nothing to do for schedules that only need system binaries. `environment.*` values are emitted as `export VAR='val';` statements ahead of the command (not a bare `VAR='val' cd ...` prefix, which in POSIX shell only scopes to the `cd` builtin and never actually reaches the command after `&&` — a real, silent bug the old generator had).
|
|
112
112
|
|
|
113
113
|
`scheduler verify` now runs this EXACT generated line (not a bare `sched.command`), under cron's actual minimal environment — never the verifying shell's `process.env`. This is deliberate: the old verify path inherited the operator's full login-shell env, which reliably masked this whole bug class. If `verify` reports `ok` today, that's an honest signal the schedule will actually fire under real cron.
|
|
114
114
|
|
|
@@ -354,7 +354,20 @@ export function buildCronCommand(sched, workDir, env, opts = {}) {
|
|
|
354
354
|
const exportStmts = Object.entries(env)
|
|
355
355
|
.map(([k, v]) => `export ${k}='${String(v).replace(/'/g, `'\\''`)}'; `)
|
|
356
356
|
.join('');
|
|
357
|
-
|
|
357
|
+
// Whole rendered chain is braced so `>> logPath 2>&1` binds to the group,
|
|
358
|
+
// not just the last simple command. Without the braces bash parses
|
|
359
|
+
// `A && B && cmd >> log 2>&1` with the redirect bound to `cmd` alone, so
|
|
360
|
+
// an nvm-source or `cd` failure earlier in the chain sends its stderr to
|
|
361
|
+
// cron mail (silently discarded on hosts with no MTA) and leaves the log
|
|
362
|
+
// file empty — the exact silent-failure class w-2026-09-13-dave-030 tracks
|
|
363
|
+
// (smarthome01 crons fired but never wrote a log line, 2026-09-09 -> 13).
|
|
364
|
+
// A leading `date -u` inside the group prints an ISO timestamp so a run
|
|
365
|
+
// that dies mid-chain still leaves dated evidence. No `$()` — cron passes
|
|
366
|
+
// the crontab line through /bin/sh -c '...' which parses the double-quoted
|
|
367
|
+
// bash-c argument and would eagerly expand $(...) at dispatch time, not
|
|
368
|
+
// at run time.
|
|
369
|
+
const chain = `date -u; ${preamble}${exportStmts}cd ${workDir} && ${sched.command}`;
|
|
370
|
+
const inner = `{ ${chain}; } >> ${logPath} 2>&1`;
|
|
358
371
|
const wrapped = `bash -c "${inner.replace(/"/g, '\\"')}"`;
|
|
359
372
|
return { inner, wrapped };
|
|
360
373
|
}
|
package/package.json
CHANGED