πŸ—οΈ Cody Master Project Bootstrap v2.0

SkillCloud & infra

Bootstrap any new project: identity, design system, staging+production, i18n, SEO, test infrastructure, 8-gate deploy pipeline. Prevents tech debt from day 0.

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the πŸ—οΈ Cody Master Project Bootstrap v2.0 skill

What this skill tells your AI

The instructions your AI receives, as published by tody-agent/codymaster in skills/cm-project-bootstrap/SKILL.md and read by ahel’s review.

Every project starts here. No exceptions. Inspired by best practices from Amp, Claude Code, Cursor, Lovable, and Manus agents.

Core Principles

ASK FIRST. BUILD SECOND. NEVER ASSUME IDENTITY.
STAGING IS MANDATORY. PRODUCTION IS EARNED.
I18N FROM DAY 1. NOT "LATER."
DESIGN SYSTEM BEFORE COMPONENTS. TOKENS BEFORE PIXELS.
SEO IS NOT AN AFTERTHOUGHT. IT'S INFRASTRUCTURE.
EVERY PROJECT GETS AN AGENTS.MD. NO EXCEPTIONS.

11-Phase Bootstrap Process

Phase 0:    Identity Lock           β€” WHO are you deploying as?
Phase 0.5:  Security Foundation     β€” HOW do we prevent secret leaks?
Phase 1:    Project Type Detection   β€” WHAT kind of project?
Phase 2:    Repository & Environments β€” WHERE does code live?
Phase 3:    Design System Foundation β€” HOW does it look?
Phase 4:    i18n From Day 1         β€” WHICH languages?
Phase 5:    SEO Foundation          β€” HOW will people find it?
Phase 6:    AGENTS.md + Git Safety  β€” HOW do agents collaborate?
Phase 7:    Test Infrastructure     β€” HOW do we catch bugs?
Phase 8:    Deploy Pipeline (8 Gates) β€” HOW does code ship?
Phase 9:    Development Workflow    β€” HOW do we work daily?

Phase 0: Identity Lock πŸ”

MANDATORY. Cannot proceed without this. Values are NOT hardcoded β€” check history, suggest, let user confirm.

Step 1: Check Identity History

Before asking anything, check if ~/.cm-identity-history.json exists. If it does, load previous identities and suggest the most recently used values.

// ~/.cm-identity-history.json β€” Auto-maintained across projects
{
  "lastUsed": "2026-03-17",
  "identities": [
    {
      "github": { "org": "my-work-org" },
      "cloudflare": { "accountId": "abc123def456ghi789jkl012mno345pqr" },
      "i18n": { "primary": "en", "targets": ["es", "fr", "de"] },
      "usedCount": 5,
      "lastProject": "my-awesome-project",
      "lastUsed": "2026-03-17"
    }
  ]
}

Step 2: Ask with Suggestions

Present the 6 questions, pre-filling from history where available. User only needs to confirm or change:

πŸ“‹ NEW PROJECT β€” Identity Setup
(Values from your last project shown as suggestions)

1. Project name (kebab-case):       ___________
2. GitHub org [my-work-org]:         β†’ Enter to keep, or type new
3. Cloudflare ID [abc12...5pqr]:     β†’ Enter to keep, or type new
4. Domain:                           ___________
5. Primary language [en]:            β†’ Enter to keep, or type new
6. Target languages [es, fr, de]:    β†’ Enter to keep, or type new

RULE: Never assume. Always show. Let user confirm. If no history exists, ask all 6 from scratch.

Step 3: Verify Identity

⚠️ BEFORE PROCEEDING β€” CONFIRM:
πŸ” GitHub Org:     {org}
☁️  Cloudflare:     {accountId}
🌐 Domain:         {domain}
πŸ—£οΈ  Languages:      {primary} (primary), {targets}
βœ… Correct? β†’ proceed
❌ Wrong?  β†’ fix before continuing

Step 4: Create .project-identity.json

{
  "projectName": "{name}",
  "github": {
    "org": "{org}",
    "repo": "{name}"
  },
  "cloudflare": {
    "accountId": "{accountId}",
    "projectName": "{name}",
    "productionBranch": "production"
  },
  "domain": {
    "production": "{domain}",
    "staging": "staging.{domain}"
  },
  "i18n": {
    "primary": "{primary}",
    "targets": ["{targets}"]
  },
  "createdAt": "{date}",
  "bootstrapVersion": "2.0"
}

Step 5: Save to History

After creating .project-identity.json, update ~/.cm-identity-history.json:

  • Add or update the identity entry
  • Increment usedCount
  • Update lastProject and lastUsed
  • This ensures next project gets pre-filled suggestions automatically

Call cm-identity-guard to verify git config matches the GitHub org BEFORE any git push.


Phase 0.5: Security Foundation πŸ›‘οΈ

NEW β€” Defense-in-depth from day 0. Secrets leak at project start when security is "later." Calls cm-safe-deploy for setup.

Step 1: Create .gitleaks.toml

Create project-level Gitleaks configuration:

# .gitleaks.toml β€” Secret Shield Config
title = "CM Secret Shield"

[extend]
useDefault = true

[[rules]]
id = "supabase-service-key"
description = "Supabase Service Role Key"
regex = '''eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9\.[a-zA-Z0-9_-]+\.[a-zA-Z0-9_-]+'''
tags = ["supabase", "jwt"]

[[rules]]
id = "generic-high-entropy"
description = "High entropy string that may be a secret"
regex = '''(?i)(api[_-]?key|secret[_-]?key|access[_-]?token|private[_-]?key|auth[_-]?token)\s*[=:]\s*['"][a-zA-Z0-9/+=]{20,}['"]'''
tags = ["generic"]

[allowlist]
paths = ['''\.gitleaks\.toml$''', '''\.dev\.vars\.example$''', '''node_modules/''', '''dist/''']

Step 2: Setup Pre-Commit Hook

# Install git pre-commit hook for secret scanning
mkdir -p .git/hooks
cat > .git/hooks/pre-commit << 'EOF'
#!/bin/sh
echo "πŸ›‘οΈ Secret Shield: scanning staged files..."
if command -v gitleaks &> /dev/null; then
  gitleaks git --pre-commit --staged --verbose
  if [ $? -ne 0 ]; then
    echo "❌ SECRET DETECTED! Commit blocked."
    exit 1
  fi
  echo "βœ… No secrets detected"
else
  echo "⚠️ Gitleaks not installed. Running basic checks..."
  STAGED=$(git diff --cached --name-only --diff-filter=ACM)
  PATTERNS="SERVICE_KEY|ANON_KEY|PRIVATE_KEY|DB_PASSWORD|SECRET_KEY|sk-[a-zA-Z0-9]{20,}"
  for file in $STAGED; do
    if echo "$file" | grep -qE '\.(js|ts|json|toml|yaml|env)$'; then
      if git diff --cached "$file" | grep -qE "$PATTERNS"; then
        echo "❌ Potential secret in: $file"
        exit 1
      fi
    fi
  done
  echo "βœ… Basic check passed"
fi
EOF
chmod +x .git/hooks/pre-commit

Step 3: Add Security Script

Add to package.json:

{
  "scripts": {
    "security:scan": "node scripts/security-scan.js || echo 'Create scripts/security-scan.js from cm-safe-deploy guidance'"
  }
}

Step 4: Create .dev.vars.example

# .dev.vars.example β€” Template for local secrets (committed to repo)
# Copy to .dev.vars and fill in real values
SUPABASE_URL=https://YOUR_PROJECT.supabase.co
SUPABASE_SERVICE_KEY=your_service_key_here
SUPABASE_ANON_KEY=your_anon_key_here

RULE: .dev.vars = real secrets (gitignored). .dev.vars.example = template (committed).


Phase 1: Project Type Detection πŸ”

Detect project type β†’ auto-select the right stack. Default UI: shadcn/ui + Tailwind. Default layout: Mobile-first. Unless user explicitly requests otherwise.

Step 1: Ask Project Type

Present these options to the user:

TypeWhen to useStack
A. Static WebsiteDocs, landing pages, portfoliosHTML + vanilla JS + CSS
B. SPA (Vite)Dashboards, apps with client routingVite + React + TypeScript + shadcn/ui
C. Cloudflare WorkersAPIs, backends, serverless functionsHono + wrangler + TypeScript
D. Fullstack (Workers + SPA)Complete apps with API + frontendHono + Vite + React + shadcn/ui
E. Content Site (Astro)Blogs, docs, content-heavy sitesAstro + MDX

UI Library Default Rules

🎨 DEFAULT UI LIBRARY: shadcn/ui + Tailwind CSS
πŸ“± DEFAULT LAYOUT: Mobile-first responsive

These defaults apply UNLESS user explicitly says otherwise.
Examples of overrides:
  - "Use Ant Design" β†’ switch to Ant Design
  - "No mobile needed" β†’ skip mobile optimization
  - "Desktop only" β†’ desktop-first layout

If user says nothing about UI β†’ use shadcn/ui + mobile-first.

Step 2: Scaffold Based on Type

Type A: Static Website
mkdir -p public/static/{css,js,img} src tests/unit docs
touch public/index.html public/static/css/design-tokens.css public/static/css/style.css public/static/js/app.js
Type B: SPA (Vite) β€” with shadcn/ui
# Check available options first
npx -y create-vite@latest --help
# Scaffold React + TypeScript
npx -y create-vite@latest ./ --template react-ts
# Install Tailwind CSS
npm install -D tailwindcss @tailwindcss/vite
# Install and init shadcn/ui
npx -y shadcn@latest init
Type C: Cloudflare Workers
npm init -y
npm install hono wrangler --save-dev
mkdir -p src tests/unit
touch src/index.ts wrangler.jsonc
Type D: Fullstack β€” with shadcn/ui
# Workers backend + Vite frontend in one repo
mkdir -p api/src frontend/src tests/{unit,integration}
npm init -y
npm install hono wrangler --save-dev
cd frontend && npx -y create-vite@latest ./ --template react-ts
npm install -D tailwindcss @tailwindcss/vite
npx -y shadcn@latest init
Type E: Astro
npx -y create-astro@latest --help
npx -y create-astro@latest ./ --template blog --typescript strict

Step 3: Install Common Dependencies

For ALL project types:

npm install --save-dev vitest

Step 4: Mobile-First Setup

For ALL projects with UI, enforce mobile-first from scaffold:

/* Mobile-first media queries β€” ALWAYS start from mobile */
/* Default styles = mobile (< 640px) */

/* sm: 640px+ */
@media (min-width: 640px) { }
/* md: 768px+ */
@media (min-width: 768px) { }
/* lg: 1024px+ */
@media (min-width: 1024px) { }
/* xl: 1280px+ */
@media (min-width: 1280px) { }
πŸ“± MOBILE-FIRST RULES:
1. Default CSS = mobile layout (no media query needed)
2. Add complexity with min-width media queries
3. Touch targets minimum 44x44px
4. Test on 375px width (iPhone SE) as baseline
5. Navigation: bottom nav or hamburger on mobile
6. Tables: horizontal scroll or card layout on mobile
7. Forms: single column, full width inputs on mobile

Phase 2: Repository & Environments 🏠

Step 1: Initialize Git

git init
git checkout -b main

Step 2: Create Staging + Production Branches

# main = staging (default)
# production = production only
git checkout -b production
git checkout main

Step 3: Configure Cloudflare Pages

npx wrangler pages project create PROJECT_NAME --production-branch production

Step 4: Add Deploy Scripts to package.json

{
  "scripts": {
    "deploy:staging": "npx wrangler pages deploy ./public --project-name=PROJECT_NAME --branch=main",
    "deploy:production": "npx wrangler pages deploy ./public --project-name=PROJECT_NAME --branch=production",
    "test": "vitest run",
    "test:gate": "npm run test"
  }
}

Adjust ./public to match your build output directory based on project type.

Step 5: Create .gitignore (Hardened)

# === Secret Shield: Mandatory Ignores ===
# Environment & secret files
.env
.env.*
!.env.example
!.env.test
.dev.vars
!.dev.vars.example
.secret-lifecycle.json

# Platform-specific secrets
*.pem
*.key
*.p12

# Build & dependencies
node_modules/
dist/
.wrangler/
.next/

# OS & IDE
.DS_Store
*.log

Phase 3: Design System Foundation 🎨

Design tokens BEFORE components. Semantic naming ALWAYS. Saved per brand β€” consistent across ALL projects of the same user/company. shadcn/ui components as default. Mobile-first always.

Step 0: Check for Existing Brand Profile

Before creating a new design system, check if ~/.cm-design-profiles/ exists. If the user has a previous design profile, reuse it for brand consistency.

// ~/.cm-design-profiles/{org-name}.json
// Auto-saved after first project. Reused for all future projects.
{
  "orgName": "my-work-org",
  "brand": {
    "name": "Acme Corp",
    "industry": "technology",
    "style": "professional-modern"
  },
  "colors": {
    "primary": { "50": "#eff6ff", "500": "#3b82f6", "600": "#2563eb", "700": "#1d4ed8" },
    "accent": { "500": "#f59e0b" },
    "success": "#22c55e",
    "warning": "#f59e0b",
    "error": "#ef4444"
  },
  "typography": {
    "fontFamily": "Inter",
    "monoFamily": "JetBrains Mono"
  },
  "ui": {
    "library": "shadcn/ui",
    "borderRadius": "0.5rem",
    "darkMode": true
  },
  "lastUpdated": "2026-03-17",
  "usedInProjects": ["my-awesome-project", "my-frontend-app"]
}

Rules:

  • If profile exists β†’ load and apply. Ask user: "Found design profile for {orgName}. Reuse it?"
  • If no profile β†’ ask user about brand/industry β†’ create new profile
  • After bootstrap, always save the design profile to ~/.cm-design-profiles/
  • Profile is updated with each new project that uses it

Step 1: Ask Brand Context (if no profile exists)

🎨 DESIGN SYSTEM SETUP

No existing design profile found. Tell me about your brand:

1. Company/Brand name:          ___________
2. Industry:                    ___________
3. Style preference:            (professional / playful / minimal / bold)
4. Primary brand color (hex):   ___________ (or "auto" to suggest)
5. Dark mode needed?            (yes / no) [default: yes]
6. UI Library:                  [shadcn/ui] (Enter to keep, or type alternative)

Step 2: Create Design Tokens

For shadcn/ui projects (default):

Design tokens are managed through tailwind.config.ts and shadcn's CSS variables. Customize app/globals.css (or src/index.css) with brand colors:

@tailwind base;
@tailwind components;
@tailwind utilities;

@layer base {
  :root {
    /* === Brand Colors (from profile or user input) === */
    --background: 0 0% 100%;
    --foreground: 222.2 84% 4.9%;
    --card: 0 0% 100%;
    --card-foreground: 222.2 84% 4.9%;
    --popover: 0 0% 100%;
    --popover-foreground: 222.2 84% 4.9%;
    --primary: 221.2 83.2% 53.3%;       /* ← Brand primary */
    --primary-foreground: 210 40% 98%;
    --secondary: 210 40% 96.1%;
    --secondary-foreground: 222.2 47.4% 11.2%;
    --muted: 210 40% 96.1%;
    --muted-foreground: 215.4 16.3% 46.9%;
    --accent: 210 40% 96.1%;
    --accent-foreground: 222.2 47.4% 11.2%;
    --destructive: 0 84.2% 60.2%;
    --destructive-foreground: 210 40% 98%;
    --border: 214.3 31.8% 91.4%;
    --input: 214.3 31.8% 91.4%;
    --ring: 221.2 83.2% 53.3%;          /* ← Brand primary */
    --radius: 0.5rem;

    /* === Additional Semantic Tokens === */
    --success: 142.1 76.2% 36.3%;
    --warning: 37.7 92.1% 50.2%;
    --info: 221.2 83.2% 53.3%;
  }

  .dark {
    --background: 222.2 84% 4.9%;
    --foreground: 210 40% 98%;
    --card: 222.2 84% 4.9%;
    --card-foreground: 210 40% 98%;
    --popover: 222.2 84% 4.9%;
    --popover-foreground: 210 40% 98%;
    --primary: 217.2 91.2% 59.8%;
    --primary-foreground: 222.2 47.4% 11.2%;
    --secondary: 217.2 32.6% 17.5%;
    --secondary-foreground: 210 40% 98%;
    --muted: 217.2 32.6% 17.5%;
    --muted-foreground: 215 20.2% 65.1%;
    --accent: 217.2 32.6% 17.5%;
    --accent-foreground: 210 40% 98%;
    --destructive: 0 62.8% 30.6%;
    --destructive-foreground: 210 40% 98%;
    --border: 217.2 32.6% 17.5%;
    --input: 217.2 32.6% 17.5%;
    --ring: 224.3 76.3% 48%;
  }
}

For vanilla/static projects:

Create design-tokens.css with CSS custom properties (see example in project scaffold). Use the same brand colors from the profile.

Step 3: Install shadcn/ui Components (SPA/Fullstack projects)

Install essential base components:

# Core layout components
npx shadcn@latest add button
npx shadcn@latest add input
npx shadcn@latest add label
npx shadcn@latest add card
npx shadcn@latest add dialog
npx shadcn@latest add dropdown-menu
npx shadcn@latest add toast
npx shadcn@latest add skeleton

Only install what's needed. Add more components as features require them.

Step 4: Mobile-First Base Styles

/* Always include these mobile-first foundations */

/* Touch-friendly interactive elements */
button, a, [role="button"] {
  min-height: 44px;
  min-width: 44px;
}

/* Responsive container */
.container {
  width: 100%;
  padding-inline: 1rem;
}

@media (min-width: 640px) { .container { padding-inline: 1.5rem; } }
@media (min-width: 1024px) { .container { max-width: 1024px; margin-inline: auto; } }
@media (min-width: 1280px) { .container { max-width: 1280px; } }

/* Safe area for mobile devices */
body {
  padding: env(safe-area-inset-top) env(safe-area-inset-right)
           env(safe-area-inset-bottom) env(safe-area-inset-left);
}

Step 5: Save Design Profile

After setting up the design system, auto-save to ~/.cm-design-profiles/{org}.json:

  • Brand colors, fonts, border radius, UI library preference
  • Add current project to usedInProjects array
  • Next project with same org β†’ instant design system reuse

Design System Rules

βœ… DO:
- Use shadcn/ui components as building blocks (SPA/Fullstack)
- Use semantic color tokens: bg-primary, text-muted-foreground
- Design mobile layout FIRST, then enhance for larger screens
- Reuse brand profile from ~/.cm-design-profiles/
- Touch targets: minimum 44x44px
- Test at 375px (iPhone SE) as baseline

❌ DON'T:
- Use raw hex colors: color: #333 β†’ use token
- Design desktop-first then "fix" mobile
- Create new color palette when brand profile exists
- Skip dark mode (enabled by default)
- Use fixed widths on mobile: width: 500px
- Ignore safe-area-inset on mobile

Phase 4: i18n From Day 1 🌍

Keep from v1 β€” enhanced to be framework-agnostic.

Step 1: Create i18n Engine

For static/vanilla projects, create i18n.js:

const i18n = {
  currentLang: 'vi',
  translations: {},

  async init(lang) {
    this.currentLang = lang || localStorage.getItem('lang') || 'vi';
    try {
      const res = await fetch(`/static/i18n/${this.currentLang}.json`);
      this.translations = await res.json();
    } catch {
      const fallback = await fetch('/static/i18n/vi.json');
      this.translations = await fallback.json();
    }
    this.apply();
  },

  t(key) {
    return key.split('.').reduce((obj, k) => obj?.[k], this.translations) || `[${key}]`;
  },

  apply() {
    document.querySelectorAll('[data-i18n]').forEach(el => {
      el.textContent = this.t(el.dataset.i18n);
    });
    document.querySelectorAll('[data-i18n-placeholder]').forEach(el => {
      el.placeholder = this.t(el.dataset.i18nPlaceholder);
    });
    document.documentElement.lang = this.currentLang;
  },

  async switchTo(lang) {
    localStorage.setItem('lang', lang);
    await this.init(lang);
  }
};

For React/Vite projects, use react-i18next:

npm install i18next react-i18next i18next-browser-languagedetector

For Astro projects, use astro-i18n or manual routing.

Step 2: Create Language Files

i18n/
β”œβ”€β”€ vi.json   ← Source of truth (primary language)
β”œβ”€β”€ en.json
β”œβ”€β”€ th.json
└── ph.json

Step 3: i18n Rules

βœ… DO:
- Write ALL user-facing strings with t() or data-i18n
- Primary language file is source of truth
- MAX 30 strings per batch when extracting
- Run i18n-sync test after every batch

❌ DON'T:
- Hardcode strings: "Save" β†’ use t('common.save')
- Add 600 strings in one shot β†’ app crashes
- Translate before primary language is complete
- Skip audit gates between batches

Phase 5: SEO Foundation πŸ”

NEW β€” Learn from Lovable & Cursor: SEO is infrastructure, not afterthought.

Step 1: HTML Head Template

Every page must include:

<!DOCTYPE html>
<html lang="vi">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">

  <!-- SEO: Title and Description -->
  <title data-i18n="meta.title">Project Name β€” Short description</title>
  <meta name="description" data-i18n-content="meta.description" content="Page description 150-160 characters">

  <!-- SEO: Open Graph -->
  <meta property="og:title" content="Project Name">
  <meta property="og:description" content="Page description">
  <meta property="og:type" content="website">
  <meta property="og:url" content="https://yourdomain.com">
  <meta property="og:image" content="https://yourdomain.com/og-image.png">

  <!-- SEO: Twitter Card -->
  <meta name="twitter:card" content="summary_large_image">
  <meta name="twitter:title" content="Project Name">
  <meta name="twitter:description" content="Page description">

  <!-- SEO: Canonical URL -->
  <link rel="canonical" href="https://yourdomain.com">

  <!-- Performance: Preconnect to fonts -->
  <link rel="preconnect" href="https://fonts.googleapis.com">
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>

  <!-- Favicon -->
  <link rel="icon" type="image/svg+xml" href="/favicon.svg">

  <!-- Styles -->
  <link rel="stylesheet" href="/static/css/design-tokens.css">
  <link rel="stylesheet" href="/static/css/style.css">
</head>
<body>
  <!-- Content with semantic HTML -->
  <header role="banner">...</header>
  <nav role="navigation" aria-label="Main">...</nav>
  <main role="main">
    <h1>One H1 per page</h1>
    ...
  </main>
  <footer role="contentinfo">...</footer>

  <script src="/static/js/i18n.js"></script>
  <script src="/static/js/app.js" defer></script>
</body>
</html>

Step 2: SEO Checklist

Every page must pass:

#CheckRule
1Title tagDescriptive, unique per page, < 60 chars
2Meta descriptionCompelling, 150-160 chars
3H1 tagExactly ONE per page
4Heading hierarchyh1 β†’ h2 β†’ h3 (no skipping)
5Semantic HTML<header>, <nav>, <main>, <footer>, <article>, <section>
6Alt attributesEvery <img> has descriptive alt text
7Canonical URLPrevents duplicate content
8Open GraphSocial sharing preview
9Lang attribute<html lang="vi"> matches current language
10Unique IDsAll interactive elements have unique, descriptive IDs

Phase 6: AGENTS.md + Git Safety πŸ€–

NEW β€” Learn from Amp & Claude Code: Project manifest for AI collaboration.

Step 1: Create AGENTS.md

Every project MUST have this file at root:

# AGENTS.md β€” Project Manifest

> This file helps AI agents understand and work with this project effectively.

## Project Overview
- **Name**: my-awesome-docs
- **Type**: Static Website (Cloudflare Pages)
- **Primary Language**: English (en)
- **Tech Stack**: HTML, vanilla JS, CSS, Cloudflare Pages

## Commands
- `npm run dev` β€” Start local dev server
- `npm run test` β€” Run all tests
- `npm run test:gate` β€” Run pre-deploy test gate
- `npm run deploy:staging` β€” Deploy to staging
- `npm run deploy:production` β€” Deploy to production

## Project Structure

public/ β€” Static files served directly static/css/ β€” Stylesheets (design-tokens.css, style.css) static/js/ β€” JavaScript (app.js, i18n.js) static/i18n/ β€” Language files (vi.json, en.json, ...) src/ β€” Backend source (if applicable) tests/ β€” Test files docs/plans/ β€” Implementation plans


## Code Conventions
- **i18n**: ALL user-facing strings must use t() or data-i18n. vi.json is source of truth.
- **CSS**: Use design tokens only. Never raw hex colors or arbitrary spacing.
- **Commits**: Conventional format β€” `feat:`, `fix:`, `docs:`, `test:`, `chore:`
- **Branches**: `main` = staging, `production` = production only
- **Deploy**: Always staging first. Production requires explicit request.

## Important Rules
1. Run `cm-identity-guard` before any git push
2. Never force push to main or production
3. i18n extraction: MAX 30 strings per batch
4. Run test:gate before every deploy
5. Check `.project-identity.json` for deploy targets
6. Use `qmd` (cm-deep-search) for semantic codebase search. Ensure `.qmd` index is fresh.

Step 2: Git Safety Protocol

Conventional Commits

From the very first commit, enforce:

feat: add user login page
fix: correct i18n key for save button
docs: update README with deploy instructions
test: add frontend safety tests
chore: update dependencies
i18n: extract settings page strings (batch 3/5)
Branch Protection Rules
main branch:
  βœ… Direct push allowed (staging)
  ❌ Never force push
  βœ… Run test:gate before deploy

production branch:
  ❌ Never direct push
  βœ… Only via: git checkout production && git merge main && git push
  βœ… Requires staging verification first
  ❌ Never force push

Shortened here. Read the whole file on GitHub.

Signals

GitHub stars
52
Forks
23
Last commit
Aug 2026

ahel review

  • K1binfo
    installs-packages

Automated review, not a security audit. Ruleset v1+k2.

Advanced
Catalog kind
skill
Gateway key
cm-project-bootstrap
Source
github.com/tody-agent/codymaster