diff --git a/docs/notes/ideas.md b/docs/notes/ideas.md index 6618289..8b3eb1b 100644 --- a/docs/notes/ideas.md +++ b/docs/notes/ideas.md @@ -74,4 +74,15 @@ Potential use cases: - Start a countdown timer subscription only during a specific game phase - Switch from animationFrame to a slower timer when entity count exceeds a threshold +- Switch from animationFrame to a slower timer when entity count exceeds a threshold + The dispatcher already handles subscription diffing (`diffSubscriptions`) — adding/removing subscriptions between commits is fully supported. This just needs a real consumer to exercise it. + +## Zero Console Policy + +This repository implements a strict zero-console policy for all source code. + +- All `console.log`, `console.info`, and `console.error` calls are prohibited in `packages/*/src`. +- This ensures that production logs are clean and prevents side-channel information leaks. +- Error handling must be managed via the MVU pattern (dispatching error messages) or silent failures where appropriate, rather than simple console output. +- Enforcement is handled via ESLint (`no-console: "error"`) and a pre-push regex check. diff --git a/eslint.config.js b/eslint.config.js index 0ecaa39..e809c6f 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -64,11 +64,15 @@ export default tseslint.config( "@typescript-eslint/no-explicit-any": "error", "@typescript-eslint/no-unused-vars": [ "error", - { argsIgnorePattern: "^_" }, + { + argsIgnorePattern: "^_", + varsIgnorePattern: "^_", + caughtErrorsIgnorePattern: "^_", + }, ], "@typescript-eslint/no-floating-promises": "error", "@typescript-eslint/switch-exhaustiveness-check": "error", - "no-console": ["warn", { allow: ["warn", "error", "info"] }], + "no-console": "error", "boundaries/element-types": [ "error", { diff --git a/packages/app-web/src/features/devtools/devtools.ts b/packages/app-web/src/features/devtools/devtools.ts index a323c95..980ea7e 100644 --- a/packages/app-web/src/features/devtools/devtools.ts +++ b/packages/app-web/src/features/devtools/devtools.ts @@ -197,8 +197,8 @@ export function view( try { const log = JSON.parse(content); onReplay(log, currentModel); - } catch (err) { - console.error("Failed to parse log", err); + } catch (_err) { + void _err; } }; reader.readAsText(file); @@ -229,8 +229,8 @@ export function view( try { const log = JSON.parse(saved); onReplay(log, currentModel); - } catch (e) { - console.error("Failed to restore", e); + } catch (_e) { + void _e; } } }, diff --git a/packages/app-web/src/main.ts b/packages/app-web/src/main.ts index 073ca32..37bf9b0 100644 --- a/packages/app-web/src/main.ts +++ b/packages/app-web/src/main.ts @@ -167,9 +167,6 @@ try { try { const log = JSON.parse(savedLogStr); if (!Array.isArray(log)) throw new Error("Log is not an array"); - console.info( - `[STORAGE] Found saved session with ${log.length} messages.`, - ); restoredModel = replay({ initialModel, @@ -201,9 +198,7 @@ try { } initialLog = log; - console.info("[STORAGE] Session restored successfully."); } catch (e) { - console.error("[STORAGE] Failed to restore session:", e); restoreError = e instanceof Error ? e.message : String(e); localStorage.removeItem("causaloop_log_v1"); } @@ -240,7 +235,6 @@ try { } } - console.info("[REPLAY] Result:", isMatched ? "MATCH" : "MISMATCH"); dispatcher.dispatch({ kind: "devtools", msg: { @@ -320,7 +314,6 @@ try { dispatcher.dispatch(msg as AppMsg), ); } catch (e) { - console.error("[FATAL] Application failed to initialize:", e); showRecoveryScreen( e instanceof Error ? `Initialization error: ${e.message}. This is likely caused by corrupted saved state.` diff --git a/packages/platform-browser/src/runners/index.ts b/packages/platform-browser/src/runners/index.ts index 66683c3..23475b3 100644 --- a/packages/platform-browser/src/runners/index.ts +++ b/packages/platform-browser/src/runners/index.ts @@ -68,8 +68,8 @@ export class BrowserRunner { this.runWrapper(effect, dispatch); break; } - } catch (err) { - console.error("Critical error in effect runner:", err); + } catch (_err) { + void _err; } } private runWrapper( diff --git a/scripts/check-forbidden.sh b/scripts/check-forbidden.sh index 8aedf3b..65843d8 100755 --- a/scripts/check-forbidden.sh +++ b/scripts/check-forbidden.sh @@ -1,7 +1,16 @@ #!/bin/bash + +# Check for eslint-disable if grep -r "eslint-disable" packages/*/src; then echo "Error: eslint-disable comments are forbidden in src directories." exit 1 fi -echo "No forbidden comments found." + +# Check for console usage +if grep -r "console\." packages/*/src; then + echo "Error: Use of console is forbidden in src directories." + exit 1 +fi + +echo "No forbidden patterns found." exit 0