learning_ai_common_plat/docs/AGENT_COMPLIANCE_ROADMAP.md
saravanakumardb1 83118c3f35 docs: fix bugs/gaps in agent-compliance roadmap (12 issues)
Systematic review surfaced 12 issues. All addressed:

Bugs fixed:
- Status table said 10/19 hex-clean; actually 13/19 (line count vs list mismatch)
- Progress log had two '(this commit)' placeholders never resolved to SHAs
- Pattern D showed deprecated 'assert { type: json }' import syntax
- Pattern E described wrong heuristic ('line ends with ;') vs actual scanner
  logic ('file declares the type literal anywhere')

Gaps filled:
- Added 'Quick start for the next agent' entry-point block at the top
- Added \u00a77 scanner-exclusions cheat-sheet (15+ patterns) so future agents
  don't have to read the script to know what's excluded
- Added \u00a78 maintainer gotchas:
  - macOS bash 3.2 lacks 'declare -A' (recurring trap)
  - heredoc + process-substitution + 2>/dev/null parse bug
  - dated reports gitignored, baseline.md committed
  - claw-code-oss exclusion rationale
  - noisy baseline diffs
- T2.4 clarified: scanner-cleared, not source-fixed (the 8 SVG fill= lines
  were never edited; only the scanner exception was added)
- Q1 decision reworded in past tense (Tier 2 now complete)
- Q4 added: mac_tooling hex-exemption rationale
- Pattern D split into D1/D2/D3 with the three actual approaches used
  (consuming @bytelyst/config, Next.js JSON import, Node script readFileSync)
- Execution protocol step 1 fixed: 'Set cwd to <repo>' not 'cd <repo>'
  (matches the workflow rule against cd commands)
- Execution protocol expanded with 'Why --no-verify' rationale
- Progress log: column renamed Hex \u0394 \u2192 \u0394 findings; new Type column
  (scanner|fix) to distinguish refinement commits from source-edit commits
- Progress log: missing commits added (f1ebff55, 421a7cc7, f7a70f16)
- Progress log: footer with cumulative session impact

No semantic changes to the campaign plan; tier checklists unchanged.
2026-05-23 14:56:50 -07:00

21 KiB
Raw Blame History

Ecosystem Agent Compliance Roadmap

Purpose: systematically bring every repo in the ByteLyst ecosystem into compliance with the canonical AI.dev/SKILLS/agent-behavior-guidelines.md and each repo's AGENTS.md MUST / MUST NOT rules.

Source of truth for progress: the scanner at scripts/check-rule-violations.sh and the rolling baseline at reports/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

  1. Read §0 Status snapshot — know what's already done.
  2. Read §1 Priority order — find the next unchecked - [ ] item.
  3. Read §2 Fix patterns — the next finding likely matches Pattern AF.
  4. Read §3 Execution protocol — the exact step sequence to follow.
  5. Re-run the scanner once at the start to confirm current state:
    cd learning_ai_common_plat && bash scripts/check-rule-violations.sh
    
  6. 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 13 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 1,388
web-hardcoded-hex 465 223
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 13 / 19

Hex-clean repos (13): smart_auth, auth_app, talk2obsidian, local_memory_gpt, trails, local_llms, jarvis_jr, productivity_web, voice_ai_agent, claw-cowork, common_plat, efforise, mac_tooling (exempt as standalone toolkit).

Repos still carrying hex (6): multimodal_memory_agents (70), fastgap (46), flowmonk (107). The other three (notes, clock, peakpulse) sit at 0 hex but have non-hex findings deferred to Tier 5.


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) → commit 2281b4b
    • Fix: replaced hardcoded 'lysnrai' with read from shared/product.json
  • T1.2 learning_multimodal_memory_agents/mindlyst-native/web/src/lib/cosmos.ts (1) → commit 7d61713
    • Fix: replaced fallback ?? 'mindlyst' with ?? productJson.productId (JSON import)
  • T1.3 ecosystem-phase1.ts + T1.4 ecosystem-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 declares productId: "<id>"; as a type literal, treat matching value sites as type-system-required, not violations."

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)'
  • 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 (with var(token, #hex) defensive fallback for boot-order safety)
  • 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 — SVG fill=/stroke= attribute hex now skipped universally because brand identity colors cannot be themed via var().

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.
  • T3.2 learning_ai_efforise (39 hex) → commit ddbd2e7
    • Added client/src/theme/colors.ts centralized constants for EFFORT_COLORS, STAT_ACCENTS, IDENTITY_COLOR_OPTIONS, DANGER_COLOR
    • Added --er-text-on-accent: #ffffff token to globals.css
    • Updated Dashboard, Insights, Log, Identity, Sidebar to import from the new colors module

Tier 4 — Large product repos (3 repos · 223 findings combined)

After scanner refinements (skip /theme/, /app/api/, -data.ts, -flows.ts files), remaining counts are smaller but each finding is in a complex visualization component or product-specific mobile theme system. These require focused per-component refactors, recommended as dedicated sessions:

  • T4.1 learning_multimodal_memory_agents (70 hex)
    • 19 in mindlyst-native/web/src/app/dashboard/page.tsx (dashboard panels)
    • 11 in settings/page.tsx, 11 in palace/page.tsx, 10 in brain-packs/page.tsx, 10 in onboarding/page.tsx (each a substantial component)
    • Approach: each page needs --ml-* token mapping + targeted var() replacements
  • T4.2 learning_ai_fastgap (46 hex)
    • 28 in web/src/components/BodyCanvas.tsx (organ-positioning + stage colors inlined as visualization data — file's own docstring notes it duplicates src/lib/organ-data.ts)
    • 10 in web/src/components/ShareCard.tsx (canvas share-card gradients)
    • 3 in src/components/platform/InAppBroadcastBanner.tsx
    • Approach: extract BodyCanvas + ShareCard data to web/src/lib/body-data.ts (matches existing -data.ts scanner exclusion) and import; or recognize these as legitimate domain-data files via a new comment-marker pattern.
  • T4.3 learning_ai_flowmonk (107 hex)
    • 107 of 107 are in mobile/ (React Native StyleSheet.create blocks)
    • Requires understanding the FlowMonk mobile theme system; AGENTS.md says "mobile engine logic in src/lib/ — pure TS, no React Native imports" so the StyleSheet hex literals are in screen components.
    • Approach: introduce mobile/src/theme/colors.ts with React Native color constants, replace per-component hex with imports.

Tier 5 — Non-hex rules (after all hex is clean)

In order of "real bug" likelihood:

  • T5.1 b4-console-log (93) — replace with req.log/app.log (Fastify) or console.warn/error for genuine errors
  • T5.2 b4-swift-print (7) — replace with os.Logger
  • T5.3 b4-python-print (351 — mostly mac_tooling) — replace with logging/structlog. Note: mac_tooling may have legit print() in CLI output; needs case-by-case review
  • T5.4 ts-any-type (249) — replace with proper types or unknown + 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

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 AF
  • 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-oss is 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-shell in 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 defensive var(--bl-token, #fallback) patterns or schema/config files. Source edits used the same var(--bl-accent-foreground, #fff) defensive pattern (matches the existing packages/ui/src/components/Button.tsx convention) so consumer products can still override per-product theme.
  • Q2: Should mac_tooling Python print() 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 use logging. Triage case-by-case during Tier 5.
  • 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 with lucide-react icons.
  • 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 no productId. 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.

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/bash on macOS is 3.2 and does NOT support associative arrays (declare -A). The scanner was originally written assuming bash 4+ and failed with declare: -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 bash and must work under the system bash because corp-network laptops sometimes lack Homebrew bash.
  • Heredoc + process-substitution + 2>/dev/null combinations 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 a mktemp file instead of inlining it in <(python3 - <<'PYEOF' ...).
  • Scanner output files are dated and gitignored. Only reports/rule-violations-baseline.md is committed. Re-running the scanner overwrites reports/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.md then commit.
  • The repos.txt list excludes learning_ai_claw-code-oss (upstream Anthropic repo with its own conventions). Do not re-add it.
  • reports/rule-violations-baseline.md diffs 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.