learning_ai_common_plat/docs/BEST_PRACTICES/PLATFORM_PLAYBOOK.md

35 KiB
Raw Blame History

ByteLyst Platform — Best Practices & New Product Playbook

For: Founders, engineers, and AI coding agents building products on the ByteLyst shared platform.

Last updated: 2026-02-28 · Ecosystem: 5 products, 16 shared packages, 43 platform modules, 1100+ service tests.


Table of Contents

  1. Platform Philosophy
  2. What You Get for Free
  3. New Product Playbook — Step by Step
  4. Expected Velocity
  5. Architecture Best Practices
  6. Coding Conventions
  7. Data & Cosmos DB Practices
  8. Auth & Security Practices
  9. Testing Practices
  10. Deployment & CI Practices
  11. AI Agent Collaboration
  12. Anti-Patterns to Avoid
  13. Real-World Examples

1. Platform Philosophy

The ByteLyst platform follows a "build once, ship five" model:

  • Product-agnostic core — every shared package and service works for any product via the productId field
  • Thin product shells — product repos contain only UI and product-specific logic; all infrastructure is shared
  • Convention over configuration — follow the patterns, get auth/billing/telemetry/flags/audit for free
  • Offline-first — clients work without connectivity and sync when online

The Three Layers

┌─────────────────────────────────────────────────────────────┐
│  PRODUCT REPO          UI + product-specific logic only     │
│  (your new app)        Next.js / SwiftUI / Compose / RN    │
└────────────────────────────┬────────────────────────────────┘
                             │  file: refs / REST API
┌────────────────────────────┴────────────────────────────────┐
│  COMMON PLATFORM           @bytelyst/* packages             │
│  (learning_ai_common_plat) platform-service (port 4003)     │
│                            extraction-service (port 4005)   │
└────────────────────────────┬────────────────────────────────┘
                             │
┌────────────────────────────┴────────────────────────────────┐
│  AZURE INFRASTRUCTURE      Cosmos DB · Blob · Key Vault     │
│                            Speech · OpenAI · Stripe         │
└─────────────────────────────────────────────────────────────┘

2. What You Get for Free

2.1 Shared Packages (16)

Every package is npm install-able via file: refs to the sibling common-plat repo.

Package What It Does You Write
@bytelyst/auth JWT sign/verify, password hash, auth middleware Nothing — just call it
@bytelyst/auth-client Client-side auth (login, register, token refresh, SSO) Wire to your login UI
@bytelyst/cosmos Cosmos DB client singleton, container registry Register your containers
@bytelyst/config Zod env loader, product identity, Key Vault resolver Your product's .env
@bytelyst/api-client Fetch wrapper with auth injection, timeout, retry Your service URLs
@bytelyst/errors Typed HTTP errors (400429) Throw them
@bytelyst/fastify-core createServiceApp() + startService() factory Your route plugins
@bytelyst/react-auth createAuthContext() → typed Provider + useAuth hook Wrap your app
@bytelyst/logger Pino-based structured logging req.log.info(...)
@bytelyst/events Typed in-memory event bus with error isolation Emit/subscribe
@bytelyst/blob Azure Blob Storage client + SAS token helpers Your container names
@bytelyst/extraction AI text extraction client Your extraction tasks
@bytelyst/monitoring Health-check utilities, Loki/Grafana helpers Your service name
@bytelyst/telemetry-client Browser/RN telemetry SDK (queue, flush, beacon) trackEvent()
@bytelyst/design-tokens JSON → CSS/TS/Kotlin/Swift token generator Your color overrides
@bytelyst/testing Shared test mocks, Fastify inject helpers Import in tests

2.2 Platform Service Modules (43)

The consolidated platform-service (port 4003) provides REST endpoints for:

Category Modules What You Get
Identity auth, sessions JWT auth, login/register, SSO, password reset, email verification, device sessions
Billing subscriptions, plans, licenses, stripe, promos Stripe integration, plan management, promo codes, license keys
Growth invitations, referrals Invite links, referral tracking, reward attribution
Ops flags, maintenance, status, ip-rules, ratelimit, jobs Feature flags with rollout %, maintenance mode, public status page, scheduled jobs
Data audit, exports, settings, notifications, delivery, push-triggers Audit log, GDPR export, user preferences, email/push delivery with templates
Content items, comments, votes, public, changelog, feedback Tracker/roadmap items, comments, voting, public roadmap, in-app feedback
Telemetry telemetry, analytics, experiments Event ingestion, error clustering, geo distribution, A/B experiments
Storage blob, products Blob SAS tokens, product registry/cache
Impersonation impersonation Admin user impersonation for debugging
Product-specific timers, routines, shared-timers, households (CM), fasting-sessions, fasting-protocols, body-stages, social-fasting, meal-log (NG), brains, memory, reflections, daily-briefs, streaks (ML) Domain CRUD — each scoped by productId

2.3 Dashboards (Product-Agnostic)

Dashboard Port What It Does
admin-web 3001 User management, audit logs, feature flags, telemetry viewer, secrets manager, mission control
tracker-web 3003 Issue tracker, public roadmap, voting, changelog

Both work for any product — they read productId from env and filter accordingly.

2.4 Infrastructure

  • Azure Cosmos DB — multi-tenant via productId partition
  • Azure Blob Storage — 6 containers (audio, transcripts, attachments, avatars, releases, backups)
  • Azure Key Vault — secrets resolution at startup via @bytelyst/config
  • Docker Compose — full stack with Traefik, Loki, Grafana
  • GitHub Actions — CI templates (lint, test, typecheck, build)
  • Husky + lint-staged — pre-commit secret scanning, linting

3. New Product Playbook — Step by Step

Day 0: Identity & Repo Setup (1 hour)

# 1. Create your product repo
mkdir learning_ai_<codename>
cd learning_ai_<codename>
git init

# 2. Choose your product identity
PRODUCT_ID="yourapp"       # lowercase, no hyphens (e.g. "nomgap", "chronomind")
BUNDLE_ID="com.saravana.${PRODUCT_ID}"
DOMAIN="${PRODUCT_ID}.app"

Create the scaffolding:

learning_ai_<codename>/
├── docs/
│   ├── PRD.md                  # Product requirements
│   └── roadmap.md              # Implementation roadmap
├── scripts/
│   └── docker-prep.sh          # Copy from any existing product repo
├── AGENTS.md                   # AI agent instructions (copy + customize template)
├── CLAUDE.md                   # Symlink or copy of AGENTS.md
├── .cursorrules                # Symlink or copy of AGENTS.md
├── .windsurfrules              # Symlink or copy of AGENTS.md
├── .gitignore
├── .env.example
└── README.md

Day 0: Register Product in Platform (30 minutes)

  1. Add product to platform-service products module:

    POST /products
    {
      "id": "<PRODUCT_ID>",
      "name": "Your App Name",
      "description": "One-liner",
      "domain": "yourapp.app",
      "bundleId": "com.saravana.yourapp"
    }
    
  2. Seed default feature flags — already automatic (see flags/seed.ts), just add your product's flags to the seed file.

  3. Add to backup/push workflows — update scripts/backup-main.sh and .windsurf/workflows/repo_*.md to include the new repo.

Day 1: Web App (Next.js) — 24 hours

mkdir web && cd web
npx create-next-app@latest . --app --typescript --tailwind --eslint
npm install zustand zod date-fns recharts

Wire the shared packages:

// package.json — add file: refs
{
  "dependencies": {
    "@bytelyst/api-client": "file:../../learning_ai_common_plat/packages/api-client",
    "@bytelyst/auth-client": "file:../../learning_ai_common_plat/packages/auth-client",
    "@bytelyst/config": "file:../../learning_ai_common_plat/packages/config",
    "@bytelyst/cosmos": "file:../../learning_ai_common_plat/packages/cosmos",
    "@bytelyst/react-auth": "file:../../learning_ai_common_plat/packages/react-auth",
    "@bytelyst/telemetry-client": "file:../../learning_ai_common_plat/packages/telemetry-client",
    "@bytelyst/errors": "file:../../learning_ai_common_plat/packages/errors"
  }
}

Create the standard src/lib/ wiring files (copy from any existing product):

File Purpose Source Package
lib/cosmos.ts Register Cosmos containers @bytelyst/cosmos
lib/auth-server.ts JWT utils for API routes @bytelyst/auth
lib/product-config.ts Product identity @bytelyst/config
lib/platform-client.ts API client for platform-service @bytelyst/api-client
lib/telemetry.ts Client telemetry init @bytelyst/telemetry-client
app/providers.tsx AuthProvider + telemetry init @bytelyst/react-auth

What you DON'T write: auth flows, JWT handling, token refresh, Cosmos client setup, error types, API client with retry/timeout, telemetry pipeline, feature flag polling.

Day 1: Native App (choose your framework) — 48 hours

Option Best For Stack
Expo (React Native) Fast cross-platform, JS ecosystem Expo SDK, expo-router, Zustand + MMKV
KMP + SwiftUI/Compose Maximum native performance Shared Kotlin, native UI shells
Pure Native Single platform focus SwiftUI (iOS) or Jetpack Compose (Android)

For any native app:

  1. Copy TelemetryService from an existing product (Swift or Kotlin)
  2. Copy PlatformApiClient / PlatformSyncManager for sync
  3. Wire @bytelyst/auth-client (or native equivalent) for auth
  4. Use design tokens from @bytelyst/design-tokens

Day 2: Product-Specific Backend Modules (24 hours per module)

Each domain module follows the same pattern:

services/platform-service/src/modules/<your-module>/
├── types.ts        # Zod schemas + TypeScript interfaces
├── repository.ts   # Cosmos DB CRUD (query, create, update, delete)
├── routes.ts       # Fastify REST endpoints
└── <module>.test.ts # Vitest tests

Template (types.ts):

import { z } from 'zod';

export interface YourDoc {
  id: string;
  productId: string; // REQUIRED — always
  userId: string;
  // ... your fields
  createdAt: string;
  updatedAt: string;
}

export const CreateYourDocSchema = z.object({
  // ... your validation
});

Template (repository.ts):

import { getContainer } from '../../lib/cosmos.js';
import type { YourDoc } from './types.js';

function container() {
  return getContainer('your_collection');
}

export async function list(productId: string, userId: string): Promise<YourDoc[]> {
  const { resources } = await container()
    .items.query<YourDoc>({
      query: 'SELECT * FROM c WHERE c.productId = @pid AND c.userId = @uid',
      parameters: [
        { name: '@pid', value: productId },
        { name: '@uid', value: userId },
      ],
    })
    .fetchAll();
  return resources;
}
// ... create, update, delete

Template (routes.ts):

import type { FastifyInstance } from 'fastify';
import { getRequestProductId } from '../../lib/request-context.js';
import { BadRequestError, NotFoundError } from '../../lib/errors.js';
import * as repo from './repository.js';
import { CreateYourDocSchema } from './types.js';

export async function yourRoutes(app: FastifyInstance) {
  app.get('/your-resource', async req => {
    const productId = getRequestProductId(req);
    return { items: await repo.list(productId, req.user!.userId) };
  });
  // ... POST, PUT, DELETE
}

Register in server.ts:

import { yourRoutes } from './modules/your-module/routes.js';
// ... inside route registration block:
await app.register(yourRoutes);

Day 3: User Dashboard (optional) — 46 hours

If your product needs a user-facing web portal, create a Next.js app in your product repo:

your-product/
└── user-dashboard-web/
    ├── src/
    │   ├── app/           # App Router pages
    │   ├── lib/           # Standard wiring files (copy pattern)
    │   └── components/    # shadcn/ui + custom
    ├── package.json       # file: refs to @bytelyst/*
    └── .env.example

The admin dashboard and tracker dashboard are already built and product-agnostic — just point them at your productId.


4. Expected Velocity

What Took Months, Now Takes Days

Based on actual delivery across 5 products (LysnrAI, MindLyst, ChronoMind, NomGap, and the platform itself):

Capability Without Platform With Platform Savings
Auth (JWT, login, register, SSO, password reset) 23 weeks 0 days (already built) 100%
Billing (Stripe, plans, subscriptions) 23 weeks 0 days 100%
Feature flags with rollout 1 week 0 days 100%
Telemetry pipeline 12 weeks 1 hour (wire client) 95%
Admin dashboard 34 weeks 0 days (shared) 100%
Audit logging 35 days 0 days 100%
GDPR data export 35 days 0 days 100%
Email delivery (templates, SendGrid) 1 week 0 days 100%
Rate limiting + IP rules 35 days 0 days 100%
Blob storage (uploads, SAS tokens) 1 week 0 days 100%
Public roadmap + issue tracker 2 weeks 0 days 100%
Client offline sync queue 1 week 2 hours (copy pattern) 90%
Design system (tokens across platforms) 12 weeks 1 hour (add product colors) 90%
New product-specific CRUD module 24 hours
Full MVP (web + mobile shell) 610 weeks 35 days ~85%

Realistic Timeline for a New Product

Day Milestone
Day 0 Repo created, product registered, AGENTS.md written
Day 1 Web app scaffolded with auth, telemetry, feature flags wired
Day 2 23 product-specific backend modules, Cosmos containers registered
Day 3 Core UI screens built, offline sync queue, user dashboard (if needed)
Day 4 Native app shells (iOS/Android) with auth + sync wired
Day 5 Polish, tests, CI, first deploy

By Day 5 you have: a fully authenticated, multi-platform app with billing, telemetry, feature flags, admin dashboard, audit logging, GDPR export, public roadmap, and offline sync — all production-grade.


5. Architecture Best Practices

5.1 Product Repo Structure

your-product/
├── web/                    # Next.js (App Router) or Expo
│   ├── src/
│   │   ├── app/            # Pages + API routes
│   │   ├── components/     # UI components
│   │   └── lib/            # Engine logic (pure TS, no framework imports)
│   └── package.json        # file: refs to @bytelyst/*
├── ios/                    # SwiftUI (if native)
├── android/                # Jetpack Compose (if native)
├── docs/                   # PRD, roadmap, research
├── scripts/                # Build/deploy scripts
├── AGENTS.md               # AI agent instructions
└── .env.example

5.2 Engine Logic Separation

Critical rule: Keep business logic in pure TypeScript/Kotlin/Swift files with zero framework dependencies.

✅ web/src/lib/fasting-timer.ts    → pure TS, testable without DOM
✅ web/src/lib/body-stages.ts      → pure TS, imported by components

❌ web/src/components/Timer.tsx     → business logic mixed with React
❌ web/src/lib/timer.ts            → imports from 'react'

This enables:

  • Unit testing without mocking React/RN
  • Sharing logic between web and native (via ports)
  • AI agents can modify engine logic confidently

5.3 Sync Architecture

Every client follows the same offline-first pattern:

Local Store (Zustand/MMKV/UserDefaults)
    │
    ├── Immediate: update local state
    ├── Fire-and-forget: POST/PUT to platform-service
    └── On failure: enqueue to offline queue
                        │
                        └── On next online: flush queue → pull remote → merge

Key files to copy from existing products:

  • offline-queue.ts (NomGap) — MMKV-backed queue with retry + exponential backoff
  • platform-sync.ts (ChronoMind) — full bidirectional sync with conflict detection
  • PlatformSyncManager.kt/swift (MindLyst) — native sync managers

6. Coding Conventions

Must Follow

Rule Why
Every Cosmos document includes productId Multi-tenant isolation
Every REST endpoint validates with Zod schemas Type safety + auto documentation
Every service propagates x-request-id Distributed tracing
Use req.log / app.log in Fastify Structured logging with request context
Use structlog in Python Same — never print()
Use theme tokens, never hardcode colors Cross-platform consistency
Commit messages: type(scope): description Changelog generation
Imports always at top of file Code style consistency

Must Not Do

Anti-Pattern Do Instead
console.log in production req.log.info(...) or analytics stub
any type in TypeScript Zod inference or explicit types
Hardcode secrets @bytelyst/config + Key Vault
Hardcode API URLs Environment variables
Math.random() for IDs in loops crypto.randomUUID() or include index
Modify tests to make them pass Fix the actual code
npm in common-plat pnpm (workspace)

7. Data & Cosmos DB Practices

Container Naming

✅ fasting_sessions       (snake_case, plural)
✅ feature_flags
❌ FastingSessions        (no PascalCase)
❌ fasting-session        (no hyphens, no singular)

Document Shape

Every document must include:

{
  id: string; // Unique ID (e.g. "session_1709234567890")
  productId: string; // ALWAYS — multi-tenant key
  // ... your fields
  createdAt: string; // ISO 8601
  updatedAt: string; // ISO 8601
}

Partition Key Strategy

  • Use productId as partition key for shared collections
  • Use id as partition key for product-specific collections with low cross-product queries
  • For high-volume telemetry: composite key like productId:yyyyMM:platform

Query Patterns

// ✅ Always filter by productId first
'SELECT * FROM c WHERE c.productId = @pid AND c.userId = @uid ORDER BY c.createdAt DESC';

// ❌ Full scan — never do this
'SELECT * FROM c';

8. Auth & Security Practices

JWT Flow

Client → POST /auth/login → platform-service → JWT (access + refresh)
Client → Authorization: Bearer <jwt> → platform-service validates
Client → 401 → silent refresh via refresh token → retry

Server-Side (Next.js API Routes)

// lib/auth-server.ts — copy from existing product
import { createJwtUtils } from '@bytelyst/auth';
export const { verifyToken, signToken, hashPassword, verifyPassword } = createJwtUtils({
  secret: process.env.JWT_SECRET!,
});

Client-Side

// lib/auth-client.ts — copy from existing product
import { createAuthClient } from '@bytelyst/auth-client';
export const authClient = createAuthClient({
  baseUrl: process.env.NEXT_PUBLIC_PLATFORM_URL!,
  storage: { getItem, setItem, removeItem }, // localStorage or MMKV
});

Security Checklist

  • Husky pre-commit: secret scan (scripts/secret-scan-staged.sh)
  • Husky pre-push: full repo scan (scripts/secret-scan-repo.sh)
  • No secrets in .env.example — only placeholder keys
  • All real secrets in Azure Key Vault
  • @bytelyst/config resolves secrets at startup
  • Rate limiting on all public endpoints
  • Edge middleware blocks unauthenticated API requests

9. Testing Practices

Test Structure

# Service tests (Vitest)
services/platform-service/src/modules/<module>/<module>.test.ts

# Web engine tests (Vitest)
web/src/lib/<module>.test.ts

# Native tests
ios/<Project>Tests/         # XCTest
android/app/src/test/       # JUnit5

# E2E tests (Playwright)
web/e2e/

Testing Rules

  1. Engine logic gets unit tests — pure functions, no mocking needed

  2. API routes get integration tests — use @bytelyst/testing Fastify inject helpers

  3. Never modify tests to make them pass — fix the code

  4. Test the module patterntypes.ts (schema validation), repository.ts (CRUD), routes.ts (HTTP)

  5. Mock external services — Cosmos, Stripe, SendGrid

  6. Run all tests before pushing:

    # Common platform
    cd learning_ai_common_plat && pnpm test
    
    # Your product web
    cd your-product/web && npm test
    
    # Typecheck
    cd your-product/web && npx tsc --noEmit
    

Current Test Counts (for reference)

Repo Tests Test Files
Platform-service 1,141 84
ChronoMind web 394 17
NomGap 430 15
ChronoMind iOS 129 8
ChronoMind Android 30

10. Deployment & CI Practices

Local Development

# Start platform-service (required for all products)
cd learning_ai_common_plat/services/platform-service
npm run dev    # port 4003

# Start your product
cd your-product/web
npm run dev    # port 3000 (or custom)

Docker / CI Builds

Product repos use file: refs to @bytelyst/* packages. These break in Docker/CI where the sibling repo isn't available. Use the tarball prep workflow:

# 1. Build packages
cd learning_ai_common_plat && pnpm build

# 2. Pack tarballs + rewrite package.json
./scripts/docker-prep.sh

# 3. Now Docker build works (no sibling repo needed)
docker build your-product/web/

# 4. Restore original package.json
./scripts/docker-prep.sh --restore

Environment Variables

# Required for every product
COSMOS_ENDPOINT=https://your-cosmos.documents.azure.com:443
COSMOS_KEY=...
JWT_SECRET=...
PRODUCT_ID=yourapp

# Platform-service URL (for client API calls)
PLATFORM_SERVICE_URL=http://localhost:4003
NEXT_PUBLIC_PLATFORM_URL=http://localhost:4003

# Optional but recommended
AZURE_BLOB_CONNECTION_STRING=...
STRIPE_SECRET_KEY=...

11. AI Agent Collaboration

AGENTS.md Is Your Contract

Every product repo MUST have an AGENTS.md at root. This is the onboarding doc for all AI coding agents (Claude, Cursor, Copilot, Windsurf, Codex). Include:

  1. Project identity — product name, ID, bundle ID, repo name
  2. Repo layout — directory tree with descriptions
  3. Tech stack — frameworks, versions, patterns
  4. Coding conventions — must-follow and must-not-do rules
  5. File ownership map — which files to touch for which domain
  6. Build & test commands — copy-pastable verification steps
  7. Common pitfalls — things agents frequently get wrong

Windsurf Workflows

Create .windsurf/workflows/ for repeatable multi-step tasks:

---
description: Build and deploy the app
---
1. Run tests
// turbo
2. Build the app
// turbo
3. Deploy to staging

Key Agent Rules

  • Agents should read AGENTS.md first before making any changes
  • Agents should never modify tests to make them pass
  • Agents should use req.log not console.log
  • Agents should always include productId in Cosmos documents
  • Agents should run typecheck + tests after making changes

12. Anti-Patterns to Avoid

Architecture Anti-Patterns

Don't Do Instead
Build a custom auth system Use @bytelyst/auth + @bytelyst/auth-client
Create a new microservice for each feature Add a module to platform-service
Inline fetch() wrappers in dashboard code Use @bytelyst/api-client factory
Put business logic in React components Pure TS in src/lib/, React in src/components/
Create a separate Cosmos database per product Share one database, partition by productId
Write your own feature flag system Use flags/poll endpoint + existing polling client
Skip offline queue Copy offline-queue.ts pattern — users will be offline

Code Anti-Patterns

Don't Do Instead
import { something } from '../../../common_plat/...' import { something } from '@bytelyst/package'
const id = Math.random().toString() const id = crypto.randomUUID()
catch (e: any) catch (e: unknown) with type narrowing
if (process.env.NODE_ENV === 'production') Feature flags via flags/poll
Copy-paste an entire module and rename Use the module template pattern in §3

Process Anti-Patterns

Don't Do Instead
Make a giant PR across 5 repos Commit incrementally per repo, push in order
Skip typecheck before pushing npx tsc --noEmit is mandatory
Forget to update AGENTS.md Keep it current — it's the agent contract
Use npm in common-plat pnpm — workspace protocol requires it
Forget pnpm build before dashboard npm install Always build packages first

13. Real-World Examples

Example: How NomGap Was Built

NomGap (fasting visualization app) was built on this platform in ~1 week:

  1. Day 0: Created learning_ai_fastgap, wrote PRD, wrote AGENTS.md
  2. Day 1: Expo (React Native) app scaffolded with:
    • Zustand + MMKV for state
    • @bytelyst/auth-client for auth
    • @bytelyst/telemetry-client for telemetry
    • Feature flag polling from platform-service
  3. Day 2: Pure engine modules in src/lib/ — fasting timer, body stages, autophagy meter, safety checks, gamification (283 tests)
  4. Day 3: Platform-service modules added — fasting-sessions, fasting-protocols, body-stages, social-fasting, meal-log
  5. Day 4: Offline queue, sync, native extensions (widgets, watch app stubs)
  6. Day 5: Store assets, CI, polish

What was NOT built from scratch: Auth, billing, telemetry, feature flags, admin dashboard, audit logging, rate limiting, email delivery — all inherited from the platform.

Example: How ChronoMind Was Built

ChronoMind (AI clock/timer) spans web (Next.js PWA), iOS (SwiftUI), Android (Compose), watchOS, macOS:

  1. Web: Next.js 16 + Zustand + Serwist (PWA). 16 pure engine modules in web/src/lib/, 12 React components, 394 tests
  2. iOS: SwiftUI with 20+ shared modules in ios/ChronoMind/Shared/, WidgetKit, Live Activities, Siri Shortcuts
  3. Android: Jetpack Compose + Room + Hilt, Glance widgets, foreground service
  4. Backend: 4 modules in platform-service (timers, routines, shared-timers, households)
  5. Sync: Bidirectional sync with offline queue, conflict detection

Total platform-service modules added: 4. Everything else (auth, billing, flags, telemetry, admin, tracker) was inherited.


Quick Reference: Copy-Paste Checklist for New Products

□ Create repo: learning_ai_<codename>
□ Write AGENTS.md (copy template, customize)
□ Create .env.example with required vars
□ Register product: POST /products to platform-service
□ Add flags to services/platform-service/src/modules/flags/seed.ts
□ Add design tokens to packages/design-tokens/ (optional)
□ Scaffold web app with file: refs to @bytelyst/*
□ Create lib/ wiring: cosmos.ts, auth-server.ts, product-config.ts, platform-client.ts
□ Create 13 backend modules in platform-service
□ Register Cosmos containers in cosmos-init.ts
□ Wire telemetry client
□ Wire feature flag polling
□ Add offline queue for sync
□ Write tests for engine logic
□ Run typecheck + tests
□ Add to backup/push workflows
□ Push to origin