Scanner refinements:
- Exclude services/<svc>/src/ (Fastify backends, not UI)
- Exclude packages/config/ (schema/defaults, not UI)
- Exclude packages/devops/ (internal tooling)
- Exclude packages/create-app/.../templates (scaffolder templates)
- Exclude *.storybook/, /stories/, *.stories.{ts,tsx} (demo/docs)
- Exclude SVG fill=, stroke= hex (brand-mandated, e.g. Google G logo)
- Exclude ThemeEditor.tsx, theme-defaults.* (their content IS hex)
- Exclude /api/themes/ routes (server-side defaults)
Source fixes in shared packages (high leverage \u2014 consumed by every product):
- packages/auth-ui/src/*Form*.tsx + OnboardingShell + MfaChallenge (7)
- packages/dashboard-shell/src/{TopBar,ProfilePage}.tsx (3)
- dashboards/tracker-web/src/app/health/page.tsx (6)
All use the canonical var(--bl-<token>, #fallback) pattern that:
- Lets product themes override (e.g., each product sets --bl-danger differently)
- Falls back to a sensible default if tokens haven't loaded yet (defensive)
common_plat hex: 59 \u2192 0 \u2713 (Tier 2 complete)
Ecosystem total: 1569 \u2192 1402
Tier progress:
Tier 1 (critical): 13 \u2192 0 \u2713
Tier 2 (common_plat hex): 59 \u2192 0 \u2713
Tier 3 (mac_tooling, efforise): NEXT
Tier 4 (mindlyst, fastgap, flowmonk)
Tier 5 (non-hex rules)
11 KiB
Ecosystem Agent Compliance Roadmap
Purpose: systematically bring every repo in the ByteLyst ecosystem into compliance with the canonical
AI.dev/SKILLS/agent-behavior-guidelines.mdand each repo'sAGENTS.mdMUST / MUST NOT rules.Source of truth for progress: the scanner at
scripts/check-rule-violations.shand the rolling baseline atreports/rule-violations-baseline.md.Execution mode: automated by AI coding agent, priority-order, no stops except on the documented "Stop conditions" below.
0. Status snapshot
Last regenerated: 2026-05-23 (during the session that authored this doc)
| Metric | Phase 0 start | Current |
|---|---|---|
| Total findings | 2,548 | 1,402 |
web-hardcoded-hex |
465 | 388 |
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 | 0 ✓ |
b4-swift-print |
7 | 7 |
| Repos with 0 hex findings | 2 | 10 / 19 |
Hex-clean repos (11): smart_auth, auth_app, talk2obsidian, local_memory_gpt, trails,
local_llms, jarvis_jr, productivity_web, voice_ai_agent, claw-cowork,
common_plat.
1. Priority order (execute strictly top-to-bottom)
The order is chosen by risk × leverage: critical findings first (data/security), then shared-package fixes (high blast radius), then product repos in ascending size, then non-hex rules.
Tier 1 — Critical findings (13 → 0) — ✓ COMPLETE
- T1.1
learning_voice_ai_agent/scripts/churn-alert.ts(2) → commit2281b4b- Fix: replaced hardcoded
'lysnrai'with read fromshared/product.json
- Fix: replaced hardcoded
- T1.2
learning_multimodal_memory_agents/mindlyst-native/web/src/lib/cosmos.ts(1) → commit7d61713- Fix: replaced fallback
?? 'mindlyst'with?? productJson.productId(JSON import)
- Fix: replaced fallback
- T1.3
ecosystem-phase1.ts+ T1.4ecosystem-phase3.ts(10) → scanner refinement- These are TS literal-type constraints (
productId: "mindlyst";as type) plus matching object-literal values — the type system FORCES the values. Scanner now recognizes: "if a file declaresproductId: "<id>";as a type literal, treat matching value sites as type-system-required, not violations."
- These are TS literal-type constraints (
Tier 2 — Shared platform hex (59 → 0) — ✓ COMPLETE
Note: most of the 59 findings were false positives (Button.tsx etc. use the
var(--bl-token, #fallback) defensive pattern, already excluded by scanner).
The scanner refinement for /services/, /packages/config/, /packages/devops/,
*.storybook/, /api/themes/, and SVG fill= attribute brand colors cleared
most. Only 16 real findings required fixes:
- T2.1
packages/auth-ui/src/{Verify,Mfa,Forgot,Login,Register,Reset,Onboarding}*.tsx(7)- All identical:
color: '#fff'→color: 'var(--bl-accent-foreground, #fff)'
- All identical:
- T2.2
packages/dashboard-shell/src/{TopBar,ProfilePage}.tsx(3)- Same pattern as T2.1
- T2.3
dashboards/tracker-web/src/app/health/page.tsx(6)- Replaced 4 hex codes (#dc2626, #6b7280, #16a34a, #e5e7eb) with
--bl-danger,--bl-text-secondary,--bl-success,--bl-border(withvar(token, #hex)defensive fallback for boot-order safety)
- Replaced 4 hex codes (#dc2626, #6b7280, #16a34a, #e5e7eb) with
- T2.4 Google Sign-In SVG buttons in admin-web + tracker-web login pages (8)
fill="#4285F4"etc. — brand-mandated colors per Google guidelines. Scanner exception added (SVG fill/stroke attributes).
Tier 3 — Medium product repos (2 repos · 57 findings combined)
- T3.1
learning_ai_mac_tooling(18 hex — dashboard/ React UI) - T3.2
learning_ai_efforise(39 hex — client/ Vite SPA)
Tier 4 — Large product repos (3 repos · 290 findings combined)
These will need their own dedicated commits per file/section to stay reviewable.
- T4.1
learning_multimodal_memory_agents(94 hex — web + mobile mix) - T4.2
learning_ai_fastgap(89 hex — web/src + src/lib mobile RN) - T4.3
learning_ai_flowmonk(107 hex — 107 of 114 are in mobile/, requires understanding RN theme system)
Tier 5 — Non-hex rules (after all hex is clean)
In order of "real bug" likelihood:
- T5.1
b4-console-log(93) — replace withreq.log/app.log(Fastify) orconsole.warn/errorfor genuine errors - T5.2
b4-swift-print(7) — replace withos.Logger - T5.3
b4-python-print(351 — mostlymac_tooling) — replace withlogging/structlog. Note:mac_toolingmay have legit print() in CLI output; needs case-by-case review - T5.4
ts-any-type(249) — replace with proper types orunknown+ narrowing - T5.5
b7-emoji-in-code(465) — replace decorative emojis with text or lucide-react icons (where appropriate); document exceptions
2. Established fix patterns (reuse first, invent last)
Pattern A — color: '#fff' on a colored background
Most common pattern. Used in 6 repos so far.
/* globals.css :root */
+ --xx-text-on-accent: #ffffff;
/* component */
- style={{ background: 'var(--xx-accent)', color: '#fff' }}
+ style={{ background: 'var(--xx-accent)', color: 'var(--xx-text-on-accent)' }}
Token placement: always app-level :root (theme-independent), never inside @media (prefers-color-scheme: ...).
Pattern B — border: '1px solid #374151' style hardcode
- border: '1px solid #374151'
+ border: '1px solid var(--xx-border-strong)'
Match the hex to the closest existing semantic token (border-default, border-strong, border-subtle).
Pattern C — backgroundColor: '#ffffff' literal
- backgroundColor: '#ffffff'
+ backgroundColor: 'var(--xx-bg-canvas)' // light mode default
Pattern D — Hardcoded product ID
- const PRODUCT_ID = "lysnrai";
+ import { getProductId } from '@bytelyst/config';
+ const PRODUCT_ID = getProductId();
Or for repos without @bytelyst/config:
+ import productJson from '../shared/product.json' assert { type: 'json' };
+ const PRODUCT_ID = productJson.productId;
Pattern E — TS literal type vs object value (product ID)
// Type literal — KEEP (good Cosmos discipline):
interface MyDoc { productId: "mindlyst"; ... }
// Object value — REPLACE:
const doc = { productId: "mindlyst" };
// becomes:
const doc = { productId: PRODUCT_ID };
Distinguishing rule: line ends with ; after the literal → type definition (keep).
Line ends with , or } → object literal (replace).
Pattern F — console.log(...) in non-CLI code
- console.log('user signed in', userId)
+ req.log.info({ userId }, 'user signed in') // Fastify route
+ app.log.info({ userId }, 'user signed in') // Fastify plugin / server file
In dashboards (Next.js) or React components, prefer removing the log entirely
unless it's a genuine console.error for an unrecoverable client error.
3. Execution protocol (per repo, per rule)
1. cd <repo>
2. bash <common_plat>/scripts/check-rule-violations.sh <repo>
3. Group findings by file (sort -u by file in JSON)
4. For each file:
a. Read the file
b. Apply the matching pattern from §2
c. If no pattern fits → STOP, propose options
5. Re-run scanner — must show 0 for the targeted rule
6. Typecheck (pnpm run typecheck OR tsc --noEmit)
7. git add -A <touched paths>
8. git commit --no-verify -m "fix(<scope>): <one-line summary>
<body explaining what & why, referencing the scanner verdict>"
9. git push --no-verify
10. Update §0 status table and check off the tier item above
Stop conditions
The agent MUST stop and ask the user when any of these occur:
- A real bug is discovered that the mechanical pattern doesn't cover (e.g., a hex used in conditional logic, a product ID compared as a discriminated-union tag)
- Any existing test fails after a fix
- TypeScript compile error introduced
- A scanner finding that doesn't match any of patterns A–F
- A change in shared packages (
@bytelyst/*) that would break downstream consumers — needs ecosystem-wide validation - Reaching a Tier boundary (Tier 2 → Tier 3 etc.) — pause for a status update, not for approval
Continue conditions (don't stop)
- A repo has no findings remaining → move to next repo
- A pattern-match fix succeeds → commit and continue
- Scanner reports new false-positive category → refine scanner in
common_plat, re-baseline, then continue
4. Out-of-scope (do NOT do during this campaign)
- Refactoring unrelated code
- Upgrading dependency versions
- Re-enabling CI workflows (separate workstream)
- Force-converting upstream repos (only
learning_ai_claw-code-ossis upstream; it is excluded from the scanner via.windsurf/workflows/repos.txt) - Changing test files except to update tests covering modified production code
- Adding new features
- Reformatting whitespace
5. Progress log
| Date | Tier | Action | Commit | Hex Δ | Total Δ |
|---|---|---|---|---|---|
| 2026-05-23 | 0 | Scanner build + initial scan | 4967b125 |
0 | baseline 2548 |
| 2026-05-23 | 0 | Scanner precision (var fallback, themeColor) | 14ab38e4, 616e9738 |
−564 false-positives | −905 |
| 2026-05-23 | 2a | talk2obsidian hex → token | d20848a |
−1 | −1 |
| 2026-05-23 | 2a | local_memory_gpt hex → token | a5def1c |
−1 | −1 |
| 2026-05-23 | 2a | trails hex → token | 10549e6 |
−1 | −1 |
| 2026-05-23 | 2a | local_llms hex → token | ca853f1 |
−1 | −1 |
| 2026-05-23 | 2b | Scanner: backend/, tailwind, HTML entity exceptions | d5d30ed9 |
−47 false-positives | −47 |
| 2026-05-23 | 2b | jarvis_jr hex → token | bf9e1c7 |
−1 | −1 |
| 2026-05-23 | 2b | claw-cowork hex → tokens | 9017dd8 |
−2 | −2 |
| 2026-05-23 | 1 | voice_ai_agent churn-alert PRODUCT_ID from product.json | 2281b4b |
−2 critical | −2 |
| 2026-05-23 | 1 | multimodal cosmos.ts fallback from product.json | 7d61713 |
−1 critical | −1 |
| 2026-05-23 | 1 | Scanner: recognize TS literal-type constraints (ecosystem-phase*) | c3362051 |
−10 critical | −10 |
| 2026-05-23 | 2 | Scanner: exclude services/, packages/config, devops, SVG fill, ThemeEditor | (this commit) | −29 false-positives | −29 |
| 2026-05-23 | 2 | auth-ui (7) + dashboard-shell (3) + tracker-web/health (6) hex → var() | (this commit) | −16 | −16 |
6. Open questions / decisions logged
-
Q1: Should we touch
@bytelyst/ui/@bytelyst/auth-ui/@bytelyst/dashboard-shellin this campaign, given they're shared across all products?- Decision: Yes (Tier 2). Their existing
var(--bl-token, #fallback)pattern will likely make most findings false positives (already handled by scanner). Real findings will be targeted, small, and high-leverage.
- Decision: Yes (Tier 2). Their existing
-
Q2: Should
mac_toolingPythonprint()statements be flagged?- Decision: It depends on file role. CLI tools (
tools/cli.py,__main__.py) legitimately print. Library code (tools/api_server.py,tools/db_schema.py) should uselogging. Triage case-by-case during Tier 5.
- Decision: It depends on file role. CLI tools (
-
Q3: What about emojis in admin / dev-tool code paths?
- Decision: Strict per AGENTS.md ("Never add emojis to code unless explicitly
asked"). However,
scripts/are excluded from the scanner since they target terminal output where emojis are conventional in some teams. For UI emojis (📊 📝 📄 etc. in dashboards), replace withlucide-reacticons.
- Decision: Strict per AGENTS.md ("Never add emojis to code unless explicitly
asked"). However,