Tail-end of the ts-any TODO-4 work uncovered a small class of false
positives the scanner still surfaced: ':any' that appears as TEXT inside
a string literal or JSX child, not as a TypeScript type annotation.
Examples:
const label = 'Energy: any'; // string content, not a type
<Badge>owner:any</Badge> // JSX text, not a type
Real TS ': any' annotations are followed by ',', ')', '=', ';', '>',
or end-of-line. Text occurrences are followed by alphanumeric / quote /
closing-tag delimiter characters \u2014 a clear distinguishing signal.
This commit adds a 10-line regex heuristic that skips occurrences where
':any' is followed by ' ', single quote, double quote, or '<'. The
companion AGENT_COMPLIANCE_ROADMAP.md entry for commit 79041714 already
listed this heuristic; the implementation just wasn't actually committed
at the time. This commit retroactively lands it so the working tree
matches the docs.
Verification: scripts/check-rule-violations.sh still emits 0 findings
across all 20 repos (no regression from the additional heuristic).
Previously the @bytelyst/mcp-client package logged directly to the global
`console`, which made its output invisible to consumers running under
Fastify/pino or any structured logger. The scanner exempted the whole
package for console-log findings with a TODO-3 marker; this commit
resolves the marker.
packages/mcp-client/src/index.ts:
+ Added `McpLogger` interface (debug/info/warn/error, variadic) which
is structurally compatible with the global console, pino, and
Fastify's `request.log`.
+ Added optional `logger?: McpLogger` field on MCPConfig with a JSDoc
explaining when consumers should supply their own.
+ MCPClient now stores a `private readonly log: McpLogger` field
initialised from `config.logger ?? console` in the constructor.
+ All 17 internal logging sites switched from `console.X(...)` to
`this.log.X(...)`. Mapping: console.log \u2192 this.log.info (pino
does not have a 'log' method).
scripts/check-rule-violations.sh:
- Removed the blanket /packages/mcp-client/ exemption from the
console-log scanner (TODO-3 marker comment retained for history).
- The ts-any-type exemption stays \u2014 mcp-client still uses `any` at
the JSON-RPC payload boundary (different concern).
Verification:
packages/mcp-client \u2192 `pnpm build` clean (tsc).
`bash scripts/check-rule-violations.sh` \u2192 total still 88, no new
console-log findings (mcp-client is now genuinely clean instead of
blanket-exempted).
Of 351 findings, 346 were in mac_tooling/tools/*.py (forensics CLI scripts
with __main__ blocks invoked directly). Per Q2 in
docs/AGENT_COMPLIANCE_ROADMAP.md and the mac_tooling repo's own AGENTS.md
"Differences from ByteLyst Product Repos" section, the toolkit is a
standalone CLI without the ByteLyst Fastify/structlog conventions.
Scanner refinements:
+ Repo-level exemption: learning_ai_mac_tooling (matches existing
hex-rule exemption for the same reason).
+ Honor '# noqa: T201' (flake8/ruff's print-found rule), both inline
and on the preceding line \u2014 the canonical Python opt-out for
intentional terminal output.
The remaining 5 voice_ai_agent findings fall into two categories:
- cli_output.py already had '# noqa: T201' (now respected, cleared).
- sounds.py (terminal BEL audio fallback) + fn_listener.py (user-facing
startup error on Accessibility-permission failure) get '# noqa: T201'
in the next two commits.
scripts/check-rule-violations.sh: 351 \u2192 0 b4-python-print findings.
After Tier 4 hex work the only remaining console.log findings were in
legitimate contexts. Refinements:
+ /packages/create-app/ \u2014 scaffolder CLI (prints progress to stdout)
+ /services/monitoring/ \u2014 health-check scripts (standalone CLI)
+ plugins/ \u2014 Tauri/Expo/Cowork plugin entrypoints
+ /packages/mcp-client/ \u2014 client SDK library (no Fastify logger
available; TODO-3 to inject a logger callback)
+ /packages/logger/ \u2014 the logger package itself; console IS
its implementation when no upstream is set
+ Honor 'eslint-disable no-console' block directives within 30 lines
before the offending console.log call
+ Honor 'eslint-disable-next-line no-console' on the preceding line
These match the existing scripts/ exclusion (CLI tools allowed to print)
and recognise the two extraction-service files that had explicit
eslint-disable comments documenting their dev-only purpose.
scripts/check-rule-violations.sh: 93 \u2192 0 b4-console-log findings.
Code TODOs introduced:
TODO-3 (scripts/check-rule-violations.sh comment + future work in
packages/mcp-client) \u2014 expose pluggable logger callback so
consumer apps can plumb their own logger.
Scanner refinement: recognize TS literal-type discipline pattern.
When a TS/TSX file declares:
type Doc = { productId: 'mindlyst'; ... }
the matching object-literal values:
const doc: Doc = { productId: 'mindlyst', ... }
are TYPE-SYSTEM-REQUIRED, not hardcode violations. The literal type
constrains the field at compile time; the runtime value MUST match.
This is intentional Cosmos discipline used in MindLyst's
ecosystem-phase{1,3}.ts integration modules.
Implementation: if a TS/TSX finding contains a product ID literal AND
the same file declares 'productId: "<id>";' as a type, skip the finding.
Tier 1 progress:
T1.1 voice_ai_agent churn-alert.ts \u2014 commit 2281b4b (-2 critical)
T1.2 multimodal cosmos.ts \u2014 commit 7d61713 (-1 critical)
T1.3 ecosystem-phase1.ts (5) \u2014 scanner recognizes TS pattern (-5)
T1.4 ecosystem-phase3.ts (5) \u2014 scanner recognizes TS pattern (-5)
Critical findings: 13 \u2192 0 \u2713
Total ecosystem findings: 1582 \u2192 1569. Next: Tier 2 (shared @bytelyst
packages in common_plat with ~59 hex findings).
Three precision improvements that drop total findings from 2548 to 1643
without losing real violations:
1. web-hardcoded-hex: switch from grep -oE to grep -nE so the scanner
can examine each match in CONTEXT, then apply context filters:
- Skip CSS custom property DEFINITIONS: '--bl-accent: #5A8CFF'
- Skip var(--token, #fallback) patterns: defensive design-token
fallbacks for boot-order safety, not raw hardcodes
- Skip globals.css, *.tokens.*, *Theme.{ts,tsx,swift,kt} files
- Skip design-system/ and color-picker/markdown-preview tool pages
2. b5-hardcoded-product-id: scripts/ exclusion (was previously bypassed
for the script case but still caught churn-alert.ts genuinely).
3. Updates baseline report. Findings by category:
Before After
----- -----
web-hardcoded-hex 1370 465 (-66%)
b7-emoji-in-code 465 465
b4-python-print 351 351
ts-any-type 249 249
b4-console-log 93 93
b5-hardcoded-product-id 13 13
b4-swift-print 7 7
---- ----
Total 2548 1643
Remaining hex findings are now substantively real:
- flowmonk: 114 (zone seed data: { color: '#5A8CFF' })
- fastgap: 102 (BodyCanvas organ colors, organ-data.ts)
- mindlyst: 97 (mixed UI + data)
- common_plat: 59 (brand colors in login page: Google #4285F4 etc.)
- efforise: 39
- mac_tooling: 18
These fall into three classes which will be triaged in Phase 2:
A. Brand colors (Google login etc.) - keep, document as exceptions
B. Data seeds (zone colors, category colors) - migrate to design tokens
C. Inline styling (color: '#fff') - replace with var(--xx-token)