Appearance
Logging
Internal diagnostics in nubos-pilot go through one logger, lib/logger.cjs, which emits structured JSON to stderr. Keeping every log line in one shape means a consumer can pipe stderr into any JSON-aware aggregator without per-module parsing.
The logger
js
const log = require('./logger.cjs');
log.info('lock acquired', { event: 'lock-acquired', component: 'core.lock', file: 'roadmap.yaml' });
log.error('spawn failed', { event: 'spawn-failed', component: 'spawn', task_id: 'T0007' });
const scoped = log.child('memory');
scoped.warn('index rebuilt from records', { event: 'memory-rebuild', dropped: 3 });Each call writes one JSON record with ts, level, msg, the optional scope, and whatever fields you pass. Levels are debug (10), info (20), warn (30), error (40); anything below the active threshold is dropped. The threshold comes from NUBOS_PILOT_LOG_LEVEL (default info), or setLevel() in tests. child(scope) namespaces a component and nests (memory.index).
Redaction is automatic
Every string and every field value passes through a redactor before it is written. It masks Anthropic/OpenAI keys, GitHub/GitLab tokens, AWS key ids, JWTs, Bearer/Basic headers, and URL userinfo, and rewrites the user's home directory to ~. You do not have to scrub fields before logging them, but do not defeat it by pre-formatting secrets into shapes the patterns miss.
The logger never throws on its own output: if the sink fails, the line is dropped rather than crashing the caller.
Rule: no console.* in lib/ or bin/np-tools/
Business logic under lib/ and the CLI handlers under bin/np-tools/ must not call console.log / console.warn / console.error / console.info / console.debug. Use the logger instead. tests/logging-policy.test.cjs enforces this and fails the suite on a new console.*.
Two things are deliberately not logger output, and stay as direct writes:
- CLI result payloads. A command's actual output is the JSON it writes to stdout via
process.stdout.write(see CLI Commands). That is the tool's contract with its caller, not a diagnostic, so it never goes through the logger. - User-facing install output. The installer prints progress and errors to the user during
npx nubos-pilot. Those few sites write to stderr directly and are listed in the test's allowlist; each addition to that allowlist is a conscious decision, not a default.
