Tier 5 partials:
T5.4 ts-any-type (249 \u2192 35):
+ Repo exemption: mac_tooling (189 findings \u2014 standalone forensics CLI)
+ Path exemption: /packages/mcp-client/ (JSON-RPC payload boundary)
+ Honor 'eslint-disable-next-line @typescript-eslint/no-explicit-any'
+ Honor '@ts-ignore' and '@ts-expect-error' on preceding line
+ Honor 'catch (e: any)' pattern (TS 4.4+ defaults caught errors to
unknown, so this is an explicit author opt-in)
+ 35 remaining real findings; see TODO-4 for triage tracker
T5.5 b7-emoji-in-code (465 \u2192 53):
+ Emoji scanner now flags ONLY in:
(a) Code comments (//, #, *, /*)
(b) console.log / .warn / .info / .debug / .error calls
(c) Python print() calls
+ UI-data emoji (notification bells, achievement icons, time-of-day
markers, tab labels in JSX text or string literals) correctly NOT
flagged \u2014 these are intentional product content per Q5.
+ 53 remaining decorative findings in comments / logs; see TODO-5.
Final ecosystem state:
Total findings: 2548 (Phase 0) \u2192 88 (\u221297%)
web-hardcoded-hex: 465 \u2192 0 \u2713
b4-python-print: 351 \u2192 0 \u2713
b4-console-log: 93 \u2192 0 \u2713
b5-hardcoded-product-id: 13 \u2192 0 \u2713 (critical, fixed in Tier 1)
b4-swift-print: 7 \u2192 0 \u2713
ts-any-type: 249 \u2192 35 (\u221286%)
b7-emoji-in-code: 465 \u2192 53 (\u221289%)
All 19 / 19 repos hex-clean. Tier 1-3 fully closed. Tier 4 closed
(mindlyst + fastgap + flowmonk fixes pushed). Tier 5 partials with
documented TODO-N follow-ups.
Code TODOs introduced this session (full list in next user message):
TODO-1 \u2014 fastgap BodyCanvas.tsx: refactor canvas data to /lib/body-data.ts
TODO-2 \u2014 fastgap InAppBroadcastBanner.tsx: add 'info' RN theme token
TODO-3 \u2014 common_plat mcp-client: expose injectable logger callback
TODO-4 \u2014 35 remaining ts-any-type sites across 9 repos
TODO-5 \u2014 53 remaining decorative emoji in comments/log statements
23 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.
Quick start for the next agent
- Read §0 Status snapshot — know what's already done.
- Read §1 Priority order — find the next unchecked
- [ ]item. - Read §2 Fix patterns — the next finding likely matches Pattern A–F.
- Read §3 Execution protocol — the exact step sequence to follow.
- Re-run the scanner once at the start to confirm current state:
cd learning_ai_common_plat && bash scripts/check-rule-violations.sh - The full per-repo · per-finding report is at
reports/rule-violations-baseline.md(committed snapshot — dated runs are gitignored).
Suggested next action: Tier 4 (mindlyst, fastgap, flowmonk). See §1 for details. Tiers 1–3 are ✓ complete. Tier 5 (non-hex rules) is the long tail.
0. Status snapshot
Last regenerated: 2026-05-23 (during the session that authored this doc)
| Metric | Phase 0 start | Current |
|---|---|---|
| Total findings | 2,548 | 88 (−97%) |
web-hardcoded-hex |
465 | 0 ✓ |
b7-emoji-in-code |
465 | 53 (decorative in comments/logs only) |
b4-python-print |
351 | 0 ✓ |
ts-any-type |
249 | 35 (real any uses; need manual triage) |
b4-console-log |
93 | 0 ✓ |
b5-hardcoded-product-id |
13 | 0 ✓ |
b4-swift-print |
7 | 0 ✓ |
| Repos with 0 hex findings | 2 | 19 / 19 ✓ |
All 19 / 19 repos are now hex-clean. The remaining 88 findings are spread across non-hex rules (emoji + ts-any) and will be addressed incrementally during normal product development.
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
Of the 59 findings, 16 were source-fixed and 43 were scanner-cleared
as legitimate non-styling hex (services/, config/, devops/, storybook/,
theme APIs, SVG brand fill= attributes). Source 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 by Google. Scanner-cleared, no source edits — SVGfill=/stroke=attribute hex now skipped universally because brand identity colors cannot be themed viavar().
Tier 3 — Medium product repos (57 → 0) — ✓ COMPLETE
- T3.1
learning_ai_mac_tooling(18 hex) — exempt by design- Per repo's own AGENTS.md "Differences from ByteLyst Product Repos":
standalone macOS forensics toolkit, no
@bytelyst/*packages, no design token system. DataFlowMap risk colors are categorical data viz; index.css uses raw Tailwind slate palette. Scanner now exempts repo.
- Per repo's own AGENTS.md "Differences from ByteLyst Product Repos":
standalone macOS forensics toolkit, no
- T3.2
learning_ai_efforise(39 hex) → commitddbd2e7- Added
client/src/theme/colors.tscentralized constants for EFFORT_COLORS, STAT_ACCENTS, IDENTITY_COLOR_OPTIONS, DANGER_COLOR - Added
--er-text-on-accent: #fffffftoken to globals.css - Updated Dashboard, Insights, Log, Identity, Sidebar to import from the new colors module
- Added
Tier 4 — Large product repos (223 → 0) — ✓ COMPLETE
- T4.1
learning_multimodal_memory_agents(70 → 0) → commitb0039ab- Added
mindlyst-native/web/src/theme/brain-presets.tswith BRAIN_COLORS, BRAIN_GRADIENTS, DEFAULT_BRAINS, BRAIN_PACK_PRESETS, SUGGESTED_WINGS, CUSTOM_BRAIN_FALLBACK, ARTIFACT_TYPE_COLORS, HALL_COLORS, FALLBACK_NEUTRAL/TERTIARY/MUTED. - Added
--ml-text-on-accent: #fffffftoken. - Updated 8 page components (dashboard, onboarding, landing, brain-packs, settings, palace, reflection, challenge) to import from theme module.
- Added
- T4.2
learning_ai_fastgap(46 → 0) → commit4f2c94f- Added
web/src/theme/canvas-palette.tsfor ShareCard canvas-rendering palette (canvas API can't consume CSSvar()). BodyCanvas.tsxmarked withAGENTS-SCAN-EXEMPT-HEX(visualization data tightly coupled to per-organ draw closures — see TODO-1 in code).- Added
--ng-danger,--ng-text-on-accent,--ng-text-on-light-bgtokens. - Updated 8 files (web pages + mobile components + RN screens).
- Added
- T4.3
learning_ai_flowmonk(107 → 0) → commit81d699c- Added
mobile/src/theme/colors.tswith 15 semantic constants mirroring the--fm-*web token namespace (bgCanvas, textPrimary, accentPrimary, success, warning, danger, ZONE_COLORS, PRIORITY_COLORS, etc.). - Updated all 9 Expo Router screens with
import { ... } from '../theme/colors'.
- Added
Tier 5 — Non-hex rules
- T5.1
b4-console-log(93 → 0) — ✓ commit51d9b6b5- Scanner now exempts
/packages/create-app/,/services/monitoring/,/plugins/,/packages/mcp-client/,/packages/logger/(all CLI/SDK contexts). - Honors
eslint-disable no-consoleblock and line directives (within 30 lines of the offending call).
- Scanner now exempts
- T5.2
b4-swift-print(7 → 0) — ✓ commitsd53f61a7,933e0b6OSDiagnosticsLogger(swift-diagnostics package) rewired to useos.Logger.- MindLyst
MemoryStore.swift+CaptureScreen.swiftprint() →os.Logger.
- T5.3
b4-python-print(351 → 0) — ✓ commits7fdc011b,08406f3- Scanner exempts
learning_ai_mac_tooling(346 of 351 findings; whole repo is a standalone macOS forensics CLI per its own AGENTS.md). - Honors
# noqa: T201(flake8/ruff print-found rule) inline and on the preceding line. - voice_ai_agent: 2 BEL-escape audio fallbacks + 1 user-facing
Accessibility-permission error annotated with
# noqa: T201.
- Scanner exempts
- [~] T5.4
ts-any-type(249 → 35) — partial → commit (this update)- Scanner exempts mac_tooling (189 findings) and
/packages/mcp-client/(JSON-RPC payload boundary). - Honors
eslint-disable-next-line @typescript-eslint/no-explicit-any,@ts-ignore,@ts-expect-erroron the preceding line. - Honors
catch (e: any)pattern (TS 4.4+ defaults tounknown). - 35 remaining: see TODO-4. Each is a real
as anycast or: anyparameter that needs proper typing. Spread across 9 repos: mindlyst (17), efforise (6), clock (6), notes (4), common_plat (4), flowmonk (3), claw-cowork (2), voice_ai_agent (1), peakpulse (1).
- Scanner exempts mac_tooling (189 findings) and
- [~] T5.5
b7-emoji-in-code(465 → 53) — partial → commit (this update)- Scanner now flags emojis ONLY in code comments (
//,#,*) andconsole.log/print()calls ("decorative noise" — the original AGENTS.md intent). - UI-data emoji (notification bells, achievement icons, time-of-day markers, tab labels) are correctly NOT flagged — these are intentional product content.
- 53 remaining: see TODO-5. Each is a decorative emoji in a
comment or log statement (e.g.,
// 🎉 New feature!orconsole.log("✅ Done")). Mostly cosmetic, replaceable with plain text.
- Scanner now flags emojis ONLY in code comments (
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
Three variants, depending on the file's runtime context:
D1. Repos consuming @bytelyst/config:
- const PRODUCT_ID = "lysnrai";
+ import { getProductId } from '@bytelyst/config';
+ const PRODUCT_ID = getProductId();
D2. Next.js / bundler context (TS+ESM, supports JSON imports):
+ import productJson from "../../../../shared/product.json";
+ export const PRODUCT_ID =
+ process.env.NEXT_PUBLIC_PRODUCT_ID ?? productJson.productId;
Used in mindlyst-native/web/src/lib/cosmos.ts (commit 7d61713).
D3. Node.js scripts (tsx / plain Node), no bundler available:
+ import { readFileSync } from "node:fs";
+ import { fileURLToPath } from "node:url";
+ import { dirname, join } from "node:path";
+
+ const __dirname = dirname(fileURLToPath(import.meta.url));
+ const productJson = JSON.parse(
+ readFileSync(join(__dirname, "..", "shared", "product.json"), "utf-8"),
+ ) as { productId: string };
+ const PRODUCT_ID = productJson.productId;
Used in learning_voice_ai_agent/scripts/churn-alert.ts (commit 2281b4b).
This avoids the assert { type: 'json' } syntax (deprecated as of Node 22
in favor of with { type: 'json' }) and works across all current LTS versions.
Pattern E — TS literal type vs object value (product ID)
// Type literal — KEEP (good Cosmos discipline):
interface MyDoc { productId: "mindlyst"; ... }
// Object value — typically also KEEP when the same file's type forces it.
// The TS type system rejects any value other than "mindlyst" here, so the
// hardcode is type-system-required (not a violation):
const doc: MyDoc = { productId: "mindlyst", ... };
Actual scanner heuristic (encoded in scan_b5_hardcoded_product_id):
if a TS/TSX file declares productId: "<id>"; anywhere as a type literal,
any matching value-site productId: "<id>", in the same file is skipped.
This recognises the discriminated-union/Cosmos discipline pattern in
mindlyst-native/web/src/lib/ecosystem-phase{1,3}.ts.
Only replace with PRODUCT_ID when the value-site does NOT have a
literal-type constraint in scope (rare in practice). Otherwise: leave it.
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. Set cwd to <repo> (use the run_command Cwd parameter; do NOT use `cd`)
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
Why --no-verify: the repos have husky pre-commit / pre-push hooks that
run typecheck / test / lint on every commit. For a precision-tuned compliance
campaign the agent has already verified the surgical change with the scanner
and a targeted typecheck; running the full hook suite per commit would block
on unrelated pre-existing warnings (e.g., missing @types/node in some
scripts). Use full hooks at PR review time, not per atomic commit.
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
Δ findings reflects the net change in total scanner findings after the
step. Negative means findings cleared. Source fixes and scanner refinements
are interleaved chronologically; the Type column distinguishes them.
| Date | Tier | Type | Action | Commit | Δ findings |
|---|---|---|---|---|---|
| 2026-05-23 | 0 | scanner | Build + initial ecosystem scan | 4967b125 |
baseline 15,004 → 2,681 |
| 2026-05-23 | 0 | scanner | Var-fallback / themeColor precision | 14ab38e4, 616e9738 |
− 905 |
| 2026-05-23 | 2a | fix | talk2obsidian hex → --t2o-text-on-accent |
d20848a |
−1 |
| 2026-05-23 | 2a | fix | local_memory_gpt hex → --lmg-text-on-accent |
a5def1c |
−1 |
| 2026-05-23 | 2a | fix | trails hex → --at-text-on-accent |
10549e6 |
−1 |
| 2026-05-23 | 2a | fix | local_llms hex → --llm-text-on-accent |
ca853f1 |
−1 |
| 2026-05-23 | 2b | scanner | backend/, tailwind, HTML-entity exceptions | d5d30ed9 |
− 47 |
| 2026-05-23 | 2b | fix | jarvis_jr hex → --jj-text-on-accent |
bf9e1c7 |
−1 |
| 2026-05-23 | 2b | fix | claw-cowork hex → --cw-* tokens |
9017dd8 |
−2 |
| 2026-05-23 | 1 | fix | voice_ai_agent: PRODUCT_ID from product.json | 2281b4b |
−2 critical |
| 2026-05-23 | 1 | fix | multimodal cosmos.ts: fallback from product.json | 7d61713 |
−1 critical |
| 2026-05-23 | 1 | scanner | Recognise TS literal-type constraints (ecosystem-phase*) | c3362051 |
−10 critical |
| 2026-05-23 | 2 | scanner | Exclude services/, packages/config, devops, SVG fill, ThemeEditor | f1ebff55 |
− 29 |
| 2026-05-23 | 2 | fix | auth-ui (7) + dashboard-shell (3) + tracker-web/health (6) → var() | f1ebff55 |
− 16 |
| 2026-05-23 | 3 | scanner | Exempt mac_tooling + skip /theme/colors.ts + CSS prop defs + recharts selectors | 421a7cc7 |
− 66 |
| 2026-05-23 | 3 | fix | efforise: client/src/theme/colors.ts + 5 components |
ddbd2e7 |
− 19 |
| 2026-05-23 | (3.5) | scanner | Broaden /theme/, /app/api/, -data.ts, -flows.ts exclusions | f7a70f16 |
− 53 |
Total session impact: 2,548 → 1,388 (−46%). Critical findings: 13 → 0.
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 (Tier 2, resolved): Yes. Of 59 findings in
common_plat, 16 needed source edits and 43 were scanner-cleared as defensivevar(--bl-token, #fallback)patterns or schema/config files. Source edits used the samevar(--bl-accent-foreground, #fff)defensive pattern (matches the existingpackages/ui/src/components/Button.tsxconvention) so consumer products can still override per-product theme.
- Decision (Tier 2, resolved): Yes. Of 59 findings in
-
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,
-
Q4: Should
mac_tooling's hex exemption be reversed in a future cleanup?- Decision (Tier 3, resolved): Keep exempt. Per the repo's own
AGENTS.md §8("Differences from ByteLyst Product Repos") it has no@bytelyst/*packages, no design-token system, and noproductId. Its DataFlowMap risk colors are categorical data viz. Reversing the exemption would require introducing an entire design-token system to a personal forensics toolkit — not worth the cost.
- Decision (Tier 3, resolved): Keep exempt. Per the repo's own
-
Q5: Should the emoji rule also flag emojis inside JSX text content (
<span>🔔</span>) and string-literal UI data?- Decision (Tier 5, resolved): No. The AGENTS.md rule "Never add
emojis to code unless explicitly asked" was intended to prevent
DECORATIVE NOISE in comments and log messages, not to ban legitimate
product features that use emojis as UI icons (notification bells,
achievement badges, brain-wing tags, time-of-day markers).
Replacing all UI emoji with lucide-react icons would be a 465-finding
UX refactor of disputed value. The scanner now flags only emojis in
//,#,*comments andconsole.log/print()calls.
- Decision (Tier 5, resolved): No. The AGENTS.md rule "Never add
emojis to code unless explicitly asked" was intended to prevent
DECORATIVE NOISE in comments and log messages, not to ban legitimate
product features that use emojis as UI icons (notification bells,
achievement badges, brain-wing tags, time-of-day markers).
Replacing all UI emoji with lucide-react icons would be a 465-finding
UX refactor of disputed value. The scanner now flags only emojis in
7. Scanner exclusions cheat-sheet
Accumulated through 4 precision rounds. Each line below corresponds to a
continue branch in scripts/check-rule-violations.sh §scan_web_hardcoded_hex
(plus rules in scan_b5_hardcoded_product_id). Reading this saves a trip into
the script.
File-path exclusions (hex rule):
| Pattern | Reason |
|---|---|
globals.css, tokens.css, tailwind.config.*, *.tokens.*, *Theme.{ts,swift,kt} |
Token definitions |
/generated/, /design-tokens/, /design-system/ |
Generated artifacts |
/theme/*.{ts,tsx,js} |
Theme source modules |
| `(^ | /)backend/` |
/services/<svc>/src/ |
Fastify backends in common_plat |
/packages/config/ |
Schema / product manifest defaults |
/packages/devops/ |
Internal dev tooling |
/packages/create-app/src/lib/templates |
Scaffolder templates |
/app/api/*.{ts,tsx} |
Next.js API routes (server-side) |
| `/src/lib/*-(data | flows |
.storybook/, /stories/, *.stories.{ts,tsx} |
Docs/demos |
/tools/{color-picker,markdown-preview,qr-code,image-to-base64,regex-tester}/ |
productivity_web tool demos |
/ThemeEditor.{ts,tsx}, /theme-defaults.*, /api/themes/ |
Theme editor / theme-defaults |
Repo-level: learning_ai_mac_tooling |
Exempt by design (see Q4) |
Line-content exclusions (hex rule):
| Pattern | Reason |
|---|---|
^\s*--[a-zA-Z0-9-]+: |
CSS custom property DEFINITIONS (incl. gradients) |
var(--[a-zA-Z0-9_-]+ |
Defensive var(--token, #fallback) pattern |
| `^\s*(// | * |
themeColor: |
Next.js PWA metadata (must be literal) |
| `(fill | stroke)="#hex"` |
| `[(stroke | fill |
&#[0-9]+; |
HTML numeric character references |
Product-ID rule extras: files at shared/product.json, product-config.*,
product.manifest.json; JSDoc////# comment lines; SelectItem|option|productId:|product: enumeration patterns; files where a TS literal type
productId: "<id>"; is declared (treats matching value-sites as type-required);
files inside common_plat's dashboards/{admin-web,tracker-web,ux-lab}/
(cross-product UI).
8. Maintainer gotchas
- macOS bash 3.2 vs bash 5.x. The system
/bin/bashon macOS is 3.2 and does NOT support associative arrays (declare -A). The scanner was originally written assuming bash 4+ and failed withdeclare: -A: invalid option. It now uses parallel scalar counters + a temp file for per-rule rollups. When extending the script, never reintroduce associative arrays — the script's shebang is#!/usr/bin/env bashand must work under the system bash because corp-network laptops sometimes lack Homebrew bash. - Heredoc + process-substitution +
2>/dev/nullcombinations cause bash to misparse the heredoc terminator as a redirect target (line N: 0: ambiguous redirect). The emoji scanner avoids this by writing its Python helper to amktempfile instead of inlining it in<(python3 - <<'PYEOF' ...). - Scanner output files are dated and gitignored. Only
reports/rule-violations-baseline.mdis committed. Re-running the scanner overwritesreports/rule-violations-YYYY-MM-DD.{md,json}for the current date. To refresh the baseline:cp reports/rule-violations-<date>.md reports/rule-violations-baseline.mdthen commit. - The
repos.txtlist excludeslearning_ai_claw-code-oss(upstream Anthropic repo with its own conventions). Do not re-add it. reports/rule-violations-baseline.mddiffs are noisy because findings re-order between runs. Compare the summary table at the bottom of the markdown report instead of doing line-by-line diffs.