diff --git a/.github/workflows/claude-code-review.yml b/.github/workflows/claude-code-review.yml new file mode 100644 index 0000000..21cb993 --- /dev/null +++ b/.github/workflows/claude-code-review.yml @@ -0,0 +1,44 @@ +name: Claude Code Review + +on: + pull_request: + types: [opened, synchronize, ready_for_review, reopened] + # Optional: Only run on specific file changes + # paths: + # - "src/**/*.ts" + # - "src/**/*.tsx" + # - "src/**/*.js" + # - "src/**/*.jsx" + +jobs: + claude-review: + # Optional: Filter by PR author + # if: | + # github.event.pull_request.user.login == 'external-contributor' || + # github.event.pull_request.user.login == 'new-developer' || + # github.event.pull_request.author_association == 'FIRST_TIME_CONTRIBUTOR' + + runs-on: ubuntu-latest + permissions: + contents: read + pull-requests: write + issues: write + id-token: write + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 1 + + - name: Run Claude Code Review + id: claude-review + uses: anthropics/claude-code-action@v1 + with: + claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} + plugin_marketplaces: 'https://github.com/anthropics/claude-code.git' + plugins: 'code-review@claude-code-plugins' + prompt: '/code-review:code-review ${{ github.repository }}/pull/${{ github.event.pull_request.number }}' + # See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md + # or https://code.claude.com/docs/en/cli-reference for available options + diff --git a/.github/workflows/claude.yml b/.github/workflows/claude.yml new file mode 100644 index 0000000..6b15fac --- /dev/null +++ b/.github/workflows/claude.yml @@ -0,0 +1,50 @@ +name: Claude Code + +on: + issue_comment: + types: [created] + pull_request_review_comment: + types: [created] + issues: + types: [opened, assigned] + pull_request_review: + types: [submitted] + +jobs: + claude: + if: | + (github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) || + (github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) || + (github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) || + (github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude'))) + runs-on: ubuntu-latest + permissions: + contents: read + pull-requests: read + issues: read + id-token: write + actions: read # Required for Claude to read CI results on PRs + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 1 + + - name: Run Claude Code + id: claude + uses: anthropics/claude-code-action@v1 + with: + claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} + + # This is an optional setting that allows Claude to read CI results on PRs + additional_permissions: | + actions: read + + # Optional: Give a custom prompt to Claude. If this is not specified, Claude will perform the instructions specified in the comment that tagged it. + # prompt: 'Update the pull request description to include a summary of changes.' + + # Optional: Add claude_args to customize behavior and configuration + # See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md + # or https://code.claude.com/docs/en/cli-reference for available options + # claude_args: '--allowed-tools Bash(gh pr *)' + diff --git a/.github/workflows/playwright-scheduled.yml b/.github/workflows/playwright-scheduled.yml new file mode 100644 index 0000000..176da1d --- /dev/null +++ b/.github/workflows/playwright-scheduled.yml @@ -0,0 +1,146 @@ +name: Playwright scheduled + +# Runs the Playwright suite weekly and on manual dispatch. +# Does NOT gate pull requests — pull-request-check.yml is unrelated. +# See QA_PLAN.md §5 for the full specification. +# +# Mirrors the cypress-manual.yml pattern: the workflow builds *this branch's +# source* with the chosen environment's `.env.` file, starts a local +# `next start` server, and runs Playwright against `http://localhost:3005`. +# This decouples the test from whatever is currently deployed at staging / +# prod URLs — newly added selectors, fixtures, and components are exercised +# against real Strapi data without waiting for a deploy. + +on: + schedule: + # Monday 06:00 UTC = Monday 10:00 Yerevan (UTC+4). + - cron: '0 6 * * 1' + workflow_dispatch: + inputs: + target_env: + description: 'Which env file to build with (controls Strapi backend, OAuth IDs, etc.)' + type: choice + required: true + default: staging + options: + - staging + - prod + scope: + description: 'Which tier to run (ignored if spec_path is provided)' + type: choice + required: true + default: all + options: + - all + - P0 + - P1 + - P2 + spec_path: + description: 'Optional specific spec file or glob (overrides scope)' + type: string + required: false + default: '' + browser: + description: 'Browser to run against' + type: choice + required: true + default: chromium + options: + - chromium + - firefox + - webkit + - all + +permissions: + contents: read + +jobs: + playwright: + name: Playwright (${{ github.event.inputs.target_env || 'staging' }} / ${{ github.event.inputs.scope || 'all' }} / ${{ github.event.inputs.browser || 'chromium' }}) + runs-on: ubuntu-latest + timeout-minutes: 45 + env: + CI: 'true' + APP_ENV: ${{ github.event.inputs.target_env || 'staging' }} + # NODE_ENV is intentionally NOT set at the job level — yarn treats + # NODE_ENV=production as a signal to skip devDependencies, which + # would drop @axe-core/playwright (used by tests/p2/a11y.spec.ts). + # The build step and the webServer block in playwright.config.ts + # each wrap their own command in `cross-env NODE_ENV=production`, + # so production mode is still enforced where it matters. + # + # The webServer block in playwright.config.ts reads APP_ENV and runs + # `next start` against the freshly-built `.next/`. baseURL stays at + # the default localhost:3005. + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version: 20 + # Intentionally NOT caching yarn — a stale runner cache was + # leaving @axe-core/playwright out of node_modules even though + # it sat in yarn.lock. Mirrors cypress-manual.yml which also + # opts out of caching. + + - name: Install dependencies + # Plain `yarn install` (no --frozen-lockfile) — matches the + # cypress-manual.yml pattern. Slower per run (~30-60s vs cached) + # but guarantees a clean node_modules every time. + run: yarn install + + - name: Decode prod env file + if: env.APP_ENV == 'prod' + run: echo "${{ secrets.ENV_PRODUCTION }}" | base64 -d > .env.prod + + - name: Decode staging env file + if: env.APP_ENV == 'staging' + run: echo "${{ secrets.ENV_STAGING }}" | base64 -d > .env.staging + + - name: Install Playwright browsers + run: yarn playwright install --with-deps ${{ github.event.inputs.browser == 'all' && 'chromium firefox webkit' || github.event.inputs.browser || 'chromium' }} + + - name: Build app + run: yarn cross-env NODE_ENV=production APP_ENV=${{ env.APP_ENV }} next build + + - name: Resolve scope path + id: scope + run: | + SPEC_PATH="${{ github.event.inputs.spec_path }}" + SCOPE="${{ github.event.inputs.scope || 'all' }}" + if [ -n "$SPEC_PATH" ]; then + echo "path=$SPEC_PATH" >> "$GITHUB_OUTPUT" + else + case "$SCOPE" in + P0) echo "path=tests/p0/" >> "$GITHUB_OUTPUT" ;; + P1) echo "path=tests/p1/" >> "$GITHUB_OUTPUT" ;; + P2) echo "path=tests/p2/" >> "$GITHUB_OUTPUT" ;; + *) echo "path=tests/" >> "$GITHUB_OUTPUT" ;; + esac + fi + + - name: Resolve Playwright projects + id: projects + run: | + BROWSER="${{ github.event.inputs.browser || 'chromium' }}" + if [ "$BROWSER" = "all" ]; then + echo "args=--project=chromium --project=firefox --project=webkit" >> "$GITHUB_OUTPUT" + else + echo "args=--project=$BROWSER" >> "$GITHUB_OUTPUT" + fi + + - name: Run Playwright + # webServer block in playwright.config.ts spawns `next start` itself + # (because APP_ENV is set), waits for http://localhost:3005, runs + # the suite, and tears the server down at the end. + run: yarn playwright test ${{ steps.scope.outputs.path }} ${{ steps.projects.outputs.args }} + + - name: Upload HTML report + if: failure() + uses: actions/upload-artifact@v4 + with: + name: playwright-report-${{ github.run_id }} + path: playwright-report + retention-days: 14 diff --git a/.gitignore b/.gitignore index d8a43d6..4e234b5 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ .vscode .history .idea/ +.codex # Logs logs @@ -116,6 +117,16 @@ dist package-lock.json .claude/settings.local.json +CLAUDE.local.md # Playwright playwright-report/ +test-results/ +blob-report/ +.playwright/ +.playwright-mcp/ + +# Local QA planning notes (do not commit) +QA_PLAN.md +QA_RECON.md +TODO.md diff --git a/AGENTS.md b/AGENTS.md index d0bc1e0..871062f 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -102,7 +102,9 @@ interface CardProps { const Card = ({ title, isActive, className }: CardProps) => { return ( -
+
{title}
); @@ -154,7 +156,7 @@ No Tailwind, no CSS-in-JS, no inline styles (except single dynamic properties li import cn from 'classnames'; import styles from './Thing.module.scss'; -
; +
; ``` ### Conditional classes @@ -162,7 +164,7 @@ import styles from './Thing.module.scss'; Always use `classnames` (imported as `cn`): ```tsx -className={cn(styles.Button, { +className={cn(styles.button, { [styles.primary]: variant === 'primary', [styles.disabled]: disabled, })} @@ -170,7 +172,7 @@ className={cn(styles.Button, { ### SCSS class naming -PascalCase for new code: `.Card`, `.Wrapper`, `.Title`. The codebase mixes PascalCase and camelCase — prefer PascalCase going forward. +camelCase for new code: `.card`, `.cardItem`, `.wrapper`, `.title`. The codebase mixes PascalCase and camelCase — prefer camelCase going forward. ### Global styles diff --git a/package.json b/package.json index c0c8702..1b5787e 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,12 @@ "test:firefox": "cypress run --browser firefox", "test:edge": "cypress run --browser edge", "test:all": "npm run test:chrome && npm run test:firefox && npm run test:edge", + "test:e2e": "playwright test --project=chromium", + "test:e2e:ui": "playwright test --project=chromium --ui", + "test:e2e:p0": "playwright test tests/p0 --project=chromium", + "test:e2e:p1": "playwright test tests/p1 --project=chromium", + "test:e2e:p2": "playwright test tests/p2 --project=chromium", + "test:e2e:report": "playwright show-report", "prepare": "husky install" }, "dependencies": { @@ -67,9 +73,11 @@ ] }, "devDependencies": { + "@axe-core/playwright": "^4.11.2", "@babel/core": "7.19.3", "@cypress/react": "^9.0.1", "@cypress/vite-dev-server": "^6.0.3", + "@playwright/test": "^1.59.1", "@types/amplitude-js": "8.16.2", "@types/classnames": "2.2.11", "@types/lodash.debounce": "4.0.7", diff --git a/playwright.config.ts b/playwright.config.ts new file mode 100644 index 0000000..7c4d286 --- /dev/null +++ b/playwright.config.ts @@ -0,0 +1,64 @@ +/// +import { defineConfig, devices } from '@playwright/test'; + +const baseURL = process.env.PLAYWRIGHT_BASE_URL || 'http://localhost:3005'; +const isCI = !!process.env.CI; + +export default defineConfig({ + testDir: './tests', + testIgnore: ['**/fixtures/**', '**/helpers/**'], + fullyParallel: true, + forbidOnly: isCI, + retries: isCI ? 2 : 1, + // Cap local workers. `next dev` compiles routes on-demand; unbounded + // parallelism starves the server and the first-hit latency blows past + // navigationTimeout on pages the compiler hasn't warmed yet. 2 is + // deliberately conservative — the suite still runs under 3 min. + workers: isCI ? 1 : 2, + reporter: [['list'], ['html', { open: 'never' }]], + use: { + baseURL, + locale: 'en-US', + trace: 'on-first-retry', + testIdAttribute: 'data-testid', + actionTimeout: 15_000, + // Raised from 30s — accommodates `next dev`'s compile-on-first-hit cost + // when multiple workers each land on cold routes simultaneously. + navigationTimeout: 60_000, + }, + projects: [ + { + name: 'chromium', + use: { ...devices['Desktop Chrome'] }, + }, + { + name: 'firefox', + use: { ...devices['Desktop Firefox'] }, + }, + { + name: 'webkit', + use: { ...devices['Desktop Safari'] }, + }, + ], + // Server selection: + // - PLAYWRIGHT_NO_SERVER=1 → don't manage one (e.g. workflow already + // started it, or running against a deployed URL). + // - APP_ENV=staging|prod → pre-built production server (`next start`). + // The CI workflow runs `next build` first, then this block boots + // `next start` against the chosen env file. See + // .github/workflows/playwright-scheduled.yml. + // - else → local `yarn dev`. + webServer: process.env.PLAYWRIGHT_NO_SERVER + ? undefined + : { + command: + process.env.APP_ENV === 'staging' || process.env.APP_ENV === 'prod' + ? `cross-env NODE_ENV=production APP_ENV=${process.env.APP_ENV} next start -p 3005` + : 'yarn dev', + url: baseURL, + reuseExistingServer: !isCI, + timeout: 180_000, + stdout: 'ignore', + stderr: 'pipe', + }, +}); diff --git a/public/ai-atlas/bg.webp b/public/ai-atlas/bg.webp new file mode 100644 index 0000000..02f4ea5 Binary files /dev/null and b/public/ai-atlas/bg.webp differ diff --git a/public/ai-atlas/data-ru.json b/public/ai-atlas/data-ru.json new file mode 100644 index 0000000..979995b --- /dev/null +++ b/public/ai-atlas/data-ru.json @@ -0,0 +1,743 @@ +{ + "brand": { + "title": "ИИ Атлас", + "kanji": "天", + "subtitle": "империя одного хоста · класс K5" + }, + "ringLabels": { + "order": { "label": "I · Оркестраторы", "theta": 270, "offset": 0.1 }, + "devEnv": { "label": "II · Среда разработки", "theta": 270 }, + "projects": { + "label": "III · Ключевые продукты", + "theta": 270, + "offset": 0.085 + }, + "territories": { "label": "IV · Влияние", "theta": 270 } + }, + + "apex": { + "id": "wolf", + "label": "WOLF", + "cjk": "天", + "sub": "основатель", + "diamond": "gold" + }, + + "order": { + "r": 0.2, + "member": { + "id": "order", + "label": "Орден", + "diamond": "blue", + "theta": 270, + "status": "ok" + } + }, + + "devEnv": { + "r": 0.4, + "members": [ + { + "id": "voice", + "label": "Голосовой Агент", + "diamond": "blue", + "theta": 330, + "status": "ok" + }, + { + "id": "qa", + "label": "QA", + "diamond": "blue", + "theta": 30, + "status": "ok" + }, + { + "id": "researcher", + "label": "Исследователь", + "diamond": "blue", + "theta": 210, + "status": "ok" + }, + { + "id": "devops", + "label": "DevOps", + "diamond": "blue", + "theta": 150, + "status": "ok" + }, + { + "id": "tools", + "label": "Инструменты и Твики", + "sub": "инфра · память · твики", + "diamond": "red", + "theta": 90, + "status": "ok" + } + ] + }, + + "projects": { + "r": 0.6, + "leadDeg": 5, + "members": [ + { + "id": "terminal", + "label": "Terminal", + "sub": "сборщик всего", + "diamond": "red", + "theta": 215, + "status": "ok", + "leadDiamond": "blue", + "territoryArc": 0, + "children": [], + "territoryLabel": "" + }, + { + "id": "multimove", + "label": "Multimove", + "sub": "соц. медиа", + "diamond": "red", + "theta": 0, + "status": "ok", + "leadDiamond": "blue", + "territoryArc": 70, + "children": [ + { + "id": "orchestrator", + "label": "Оркестратор", + "diamond": "gold", + "status": "ok" + }, + { + "id": "telegram", + "label": "Telegram", + "diamond": "blue", + "status": "ok" + }, + { + "id": "linkedin", + "label": "LinkedIn", + "diamond": "blue", + "status": "ok" + }, + { + "id": "twitter", + "label": "Twitter", + "diamond": "blue", + "status": "ok" + }, + { + "id": "medium", + "label": "Medium", + "diamond": "blue", + "status": "ok" + } + ], + "territoryLabel": "КОНТЕНТ · PR" + }, + { + "id": "agentsforge", + "label": "AgentsForge", + "sub": "разработка AI-персон", + "diamond": "red", + "theta": 270, + "status": "ok", + "leadDiamond": "blue", + "leadDeg": 0, + "leadR": 0.54, + "territoryArc": 36, + "children": [ + { + "id": "af-redacted-2", + "label": "EMBER", + "kind": "filled", + "status": "ok", + "redacted": true + } + ], + "territoryLabel": "B2C | B2B2C" + }, + { + "id": "elea", + "label": "elea", + "sub": "разведка", + "diamond": "red", + "theta": 90, + "status": "ok", + "leadDiamond": "blue", + "leadDeg": 0, + "leadR": 0.54, + "territoryArc": 36, + "children": [ + { + "id": "choir", + "label": "Choir", + "kind": "filled", + "status": "ok", + "redacted": true + }, + { + "id": "echo", + "label": "Echo", + "kind": "filled", + "status": "ok", + "redacted": true + }, + { + "id": "whisper", + "label": "Whisper", + "diamond": "red", + "kind": "filled", + "status": "ok" + } + ], + "territoryLabel": "B2B SAAS" + }, + { + "id": "keepsimple", + "label": "KeepSimple", + "sub": "open-source крыло", + "diamond": "red", + "theta": 180, + "status": "ok", + "leadDiamond": "gold", + "territoryArc": 70, + "children": [ + { + "id": "vibecode", + "label": "Vibecode Group", + "kind": "filled", + "status": "ok" + }, + { + "id": "ks-group", + "label": "KeepSimple Channel", + "kind": "filled", + "status": "ok" + }, + { + "id": "nasa", + "label": "NASA", + "diamond": "red", + "kind": "filled", + "status": "ok" + }, + { + "id": "arc", + "label": "Arc Of Self", + "diamond": "red", + "kind": "filled", + "status": "ok" + }, + { + "id": "ks-io", + "label": "KeepSimple.io", + "diamond": "red", + "kind": "filled", + "status": "ok" + }, + { + "id": "ks-soc", + "label": "UX Core", + "diamond": "red", + "kind": "filled", + "status": "ok" + } + ], + "territoryLabel": "ОБРАЗОВАНИЕ", + "territoryReverse": true + } + ] + }, + + "territoryR": 0.82, + + "dossiers": { + "wolf": { + "title": "WOLF", + "cjk": "天", + "desc": "Владелец системы. Управляет сетью через агента Орден. Строит продукты через Терминал.", + "rows": [ + { "k": "тип", "v": "человек", "cls": "gold" }, + { "k": "кольцо", "v": "0 — вершина" }, + { "k": "преемник", "v": "Орден", "cls": "blue", "ref": "order" } + ] + }, + + "order": { + "title": "ОРДЕН", + "cjk": "令", + "desc": "Единственный обитатель Кольца I. Хранит ключи; распределяет полномочия наружу.", + "rows": [ + { "k": "тип", "v": "ИИ-агент", "cls": "blue" }, + { "k": "роль", "v": "руководитель штаба" }, + { "k": "полномочия", "v": "полные · секреты · инфра · ingress" }, + { "k": "подчиняется", "v": "Wolf", "cls": "gold", "ref": "wolf" }, + { "k": "кольцо", "v": "I — оркестраторы" } + ] + }, + + "tools": { + "title": "ИНСТРУМЕНТЫ И ТВИКИ", + "cjk": "工具", + "desc": "Общая инфраструктура, которая даёт каждому агенту на этом сервере руки, глаза и память. Ниже — четыре слоя плюс набор твиков, формирующих повседневное поведение агентов.", + "rows": [ + { "k": "тип", "v": "продукт", "cls": "red" }, + { "k": "кольцо", "v": "II — среда разработки" }, + { + "k": "поверхности", + "v": "Apex Launcher (живой дашборд) + Wolf's Terminal (шелл агентов)." + }, + { "k": "боты", "v": "Различные боты узкого и общего назначения." }, + { + "k": "память", + "v": "[MemPalace](https://github.com/mksglu/context-mode) (долгосрочная по проектам) · [context-mode](https://github.com/mksglu/context-mode) (98 КБ → 1.3 КБ, ~99% сокращение шума)." + }, + { + "k": "твики", + "v": "[каскад CLAUDE.md](tip:Статичные правила, наслаиваемые глобально → проект → подпроект; конституция, которую каждый агент читает при старте.) · [QA Officer](tip:Общий QA-мозг для всех проектов: память отпечатков с учётом изменений, доступность, web vitals, визуальная регрессия.) · [gitops-обёртка](tip:Один PAT, одна закреплённая идентичность; все git- и GitHub-операции каждого агента идут через неё.)." + } + ] + }, + + "voice": { + "title": "ГОЛОСОВОЙ АГЕНТ", + "cjk": "声", + "desc": "Универсальный голосовой шлюз. Маршрутизирует команды, транскрибирует речь (Whisper), синтезирует ответы (ElevenLabs), защищён от имитации голоса.", + "rows": [ + { "k": "тип", "v": "ИИ-агент", "cls": "blue" }, + { "k": "роль", "v": "голосовой интерфейс" }, + { "k": "полномочия", "v": "чтение хоста · бинарные подтверждения" }, + { "k": "подчиняется", "v": "Орден", "cls": "blue", "ref": "order" }, + { "k": "кольцо", "v": "II — среда разработки" } + ] + }, + + "qa": { + "title": "QA", + "cjk": "験", + "desc": "Общий QA-мозг для всех проектов: память отпечатков с учётом изменений, проверки доступности, web vitals, визуальная регрессия. Читает каждый продукт глазами пользователя, шлёт отчёты.", + "rows": [ + { "k": "тип", "v": "ИИ-агент", "cls": "blue" }, + { "k": "роль", "v": "контроль качества" }, + { "k": "полномочия", "v": "обзор · тесты · отчёты" }, + { "k": "подчиняется", "v": "Орден", "cls": "blue", "ref": "order" }, + { "k": "кольцо", "v": "II — среда разработки" } + ] + }, + + "researcher": { + "title": "ИССЛЕДОВАТЕЛЬ", + "cjk": "究", + "desc": "Глаза и руки в открытом вебе. Управляет реальным браузером как живой пользователь, проводит углублённый ресёрч по интернету и выполняет ресёрч-задачи других агентов.", + "rows": [ + { "k": "тип", "v": "ИИ-агент", "cls": "blue" }, + { "k": "роль", "v": "внешняя разведка" }, + { "k": "полномочия", "v": "веб · соц. сети · только сводки" }, + { "k": "подчиняется", "v": "Орден", "cls": "blue", "ref": "order" }, + { "k": "кольцо", "v": "II — среда разработки" } + ] + }, + + "devops": { + "title": "DEVOPS", + "cjk": "運", + "desc": "Продолжение рук Ордена в части гигиены контейнеров: сборки, рестарты, healthcheck'и. Трогает образы, не секреты.", + "rows": [ + { "k": "тип", "v": "ИИ-агент", "cls": "blue" }, + { "k": "роль", "v": "ops руки" }, + { "k": "полномочия", "v": "контейнеры · сборки · логи" }, + { "k": "подчиняется", "v": "Орден", "cls": "blue", "ref": "order" }, + { "k": "кольцо", "v": "II — среда разработки" } + ] + }, + + "terminal": { + "title": "TERMINAL — СБОРЩИК ВСЕГО", + "cjk": "端末", + "desc": "Преемник open-source проекта [Wolf's Basement](https://github.com/manager/wolfs-basement). Высокооптимизированный CLI-мультиплексор, позволяющий запускать 6+ агентов (Claude, ChatGPT и любых других) одновременно. Спроектирован, чтобы сделать совместную работу агентов максимально простой.", + "rows": [ + { "k": "тип", "v": "продукт", "cls": "red" }, + { "k": "кольцо", "v": "III — ключевые продукты" }, + { + "k": "лид", + "v": "ИИ инженерный агент", + "cls": "blue", + "ref": "lead-terminal" + }, + { + "k": "init audit", + "v": "Каждый день обходит CLAUDE.md всех агентов. Находит самые жирные точки оптимизации, будит нужного агента и предлагает ему патч." + }, + { + "k": "access table", + "v": "Живая карта зоны поражения: кто и куда может читать/писать между контейнерами и проектами." + }, + { + "k": "auto-warm", + "v": "Согласованный keep-alive между вкладками; один пинг на цель, не N вкладок × M агентов." + }, + { + "k": "byo auth", + "v": "Слоты для своих OAuth-токенов (Anthropic, OpenAI Codex). Агенты на разных биллингах в одном окне." + }, + { + "k": "send-to", + "v": "Перешли полный ответ одного агента другому с новой инструкцией — один клик, payload едет с письмом." + } + ] + }, + "multimove": { + "title": "MULTIMOVE", + "cjk": "動", + "desc": "Автоматизирует работу с соц.медиа активами команды KeepSimple на всех публичных каналах.", + "rows": [ + { "k": "тип", "v": "продукт", "cls": "red" }, + { "k": "кольцо", "v": "III — ключевые продукты" }, + { + "k": "лид", + "v": "ИИ инженерный агент", + "cls": "blue", + "ref": "lead-multimove" + }, + { "k": "владеет", "v": "контент / PR-территория" } + ] + }, + "keepsimple": { + "title": "KEEPSIMPLE — OPEN SOURCE КРЫЛО", + "cjk": "公", + "desc": "Основано в 2019. Open-source движение на стыке когнитивной науки, продукта и инженерии — инструменты, фреймворки и материалы, которыми пользуются 300 000+ человек по всему миру.", + "rows": [ + { "k": "тип", "v": "продукт", "cls": "red" }, + { "k": "кольцо", "v": "III — ключевые продукты" }, + { + "k": "лид", + "v": "человек · технический лид", + "cls": "gold", + "ref": "lead-keepsimple" + }, + { "k": "владеет", "v": "созвездие публичного влияния" } + ] + }, + "elea": { + "title": "ELEA", + "cjk": "子", + "desc": "Легальная киберразведка.", + "rows": [ + { "k": "тип", "v": "продукт", "cls": "red" }, + { "k": "кольцо", "v": "III — ключевые продукты" }, + { + "k": "лид", + "v": "ИИ инженерный агент", + "cls": "blue", + "ref": "lead-elea" + }, + { "k": "владеет", "v": "[ЗАСЕКРЕЧЕНО] · 3 сущности" } + ] + }, + "agentsforge": { + "title": "AGENTSFORGE", + "cjk": "鍛", + "desc": "Агентные ИИ-персоны, основанные на поведенческой науке.", + "rows": [ + { "k": "тип", "v": "продукт", "cls": "red" }, + { "k": "кольцо", "v": "III — ключевые продукты" }, + { + "k": "лид", + "v": "ИИ инженерный агент", + "cls": "blue", + "ref": "lead-agentsforge" + }, + { "k": "владеет", "v": "[ЗАСЕКРЕЧЕНО] · 1 сущность" }, + { "k": "url", "v": "agentsforge.com" } + ] + }, + "af-redacted-2": { + "title": "[ЗАСЕКРЕЧЕНО]", + "cjk": "秘", + "desc": "Stealth-mode продукт AgentsForge. Декодирование перехвачено.", + "rows": [ + { "k": "тип", "v": "ИИ-агент", "cls": "blue" }, + { + "k": "владелец", + "v": "AgentsForge", + "cls": "red", + "ref": "agentsforge" + }, + { "k": "статус", "v": "в кузнице" } + ] + }, + + "lead-keepsimple": { + "title": "ТЕХНИЧЕСКИЙ ЛИД · KEEPSIMPLE", + "cjk": "長", + "desc": "Человек-куратор open-source крыла.", + "rows": [ + { "k": "тип", "v": "человек", "cls": "gold" }, + { "k": "кольцо", "v": "III — ключевые продукты" }, + { "k": "пара", "v": "KeepSimple", "cls": "red", "ref": "keepsimple" } + ] + }, + + "lead-terminal": { + "title": "ТЕХНИЧЕСКИЙ ЛИД · TERMINAL", + "cjk": "長", + "desc": "Технический лид, прикреплён к проекту Terminal.", + "rows": [ + { "k": "тип", "v": "ИИ-агент", "cls": "blue" }, + { "k": "роль", "v": "технический лид" }, + { "k": "полномочия", "v": "кодовая база terminal · эскалация инфры" }, + { "k": "подчиняется", "v": "Wolf", "cls": "gold", "ref": "wolf" }, + { "k": "кольцо", "v": "III — ключевые продукты" } + ] + }, + + "lead-multimove": { + "title": "ТЕХНИЧЕСКИЙ ЛИД · MULTIMOVE", + "cjk": "長", + "desc": "Технический лид, прикреплён к проекту Multimove.", + "rows": [ + { "k": "тип", "v": "ИИ-агент", "cls": "blue" }, + { "k": "роль", "v": "технический лид" }, + { + "k": "полномочия", + "v": "кодовая база multimove · оркестрация каналов" + }, + { "k": "подчиняется", "v": "Wolf", "cls": "gold", "ref": "wolf" }, + { "k": "кольцо", "v": "III — ключевые продукты" } + ] + }, + + "lead-elea": { + "title": "ТЕХНИЧЕСКИЙ ЛИД · ELEA", + "cjk": "長", + "desc": "Технический лид, прикреплён к проекту elea.", + "rows": [ + { "k": "тип", "v": "ИИ-агент", "cls": "blue" }, + { "k": "роль", "v": "технический лид" }, + { "k": "полномочия", "v": "кодовая база elea · эскалация инфры" }, + { "k": "подчиняется", "v": "Wolf", "cls": "gold", "ref": "wolf" }, + { "k": "кольцо", "v": "III — ключевые продукты" } + ] + }, + + "lead-agentsforge": { + "title": "ТЕХНИЧЕСКИЙ ЛИД · AGENTSFORGE", + "cjk": "長", + "desc": "Технический лид, прикреплён к проекту AgentsForge.", + "rows": [ + { "k": "тип", "v": "ИИ-агент", "cls": "blue" }, + { "k": "роль", "v": "технический лид" }, + { + "k": "полномочия", + "v": "кодовая база agentsforge · эскалация инфры" + }, + { "k": "подчиняется", "v": "Wolf", "cls": "gold", "ref": "wolf" }, + { "k": "кольцо", "v": "III — ключевые продукты" } + ] + }, + + "orchestrator": { + "title": "ОРКЕСТРАТОР", + "cjk": "指", + "desc": "Человек-координатор внутри территории Multimove.", + "rows": [ + { "k": "тип", "v": "человек", "cls": "gold" }, + { "k": "владелец", "v": "Multimove", "cls": "red", "ref": "multimove" } + ] + }, + + "whisper": { + "title": "WHISPER", + "cjk": "囁", + "desc": "B2B SaaS — тихий слушающий слой (территория elea).", + "rows": [ + { "k": "тип", "v": "продукт", "cls": "red" }, + { "k": "владелец", "v": "elea", "cls": "red", "ref": "elea" } + ] + }, + "echo": { + "title": "[ЗАСЕКРЕЧЕНО]", + "cjk": "秘", + "desc": "Stealth-mode продукт. Декодирование перехвачено.", + "rows": [ + { "k": "тип", "v": "продукт", "cls": "red" }, + { "k": "владелец", "v": "elea", "cls": "red", "ref": "elea" }, + { "k": "статус", "v": "в стелсе" } + ] + }, + "choir": { + "title": "[ЗАСЕКРЕЧЕНО]", + "cjk": "秘", + "desc": "Stealth-mode продукт. Декодирование перехвачено.", + "rows": [ + { "k": "тип", "v": "продукт", "cls": "red" }, + { "k": "владелец", "v": "elea", "cls": "red", "ref": "elea" }, + { "k": "статус", "v": "в стелсе" } + ] + }, + + "vibecode": { + "title": "VIBECODE GROUP", + "cjk": "波", + "desc": "Telegram-группа, где команда KeepSimple отвечает на вопросы в прямом эфире.", + "rows": [ + { "k": "тип", "v": "группа" }, + { + "k": "владелец", + "v": "KeepSimple", + "cls": "red", + "ref": "keepsimple" + }, + { "k": "url", "v": "https://t.me/vibecodearmenia" } + ] + }, + "ks-group": { + "title": "KEEPSIMPLE CHANNEL", + "cjk": "群", + "desc": "Курируемый Telegram-канал по когнитивным и поведенческим наукам.", + "rows": [ + { "k": "тип", "v": "канал" }, + { + "k": "владелец", + "v": "KeepSimple", + "cls": "red", + "ref": "keepsimple" + }, + { "k": "url", "v": "https://t.me/keepsimple" } + ] + }, + "ks-io": { + "title": "KEEPSIMPLE.IO", + "cjk": "簡", + "desc": "Дом движения KeepSimple в вебе. Хостит UX Core, фреймворк управления Pyramids и библиотеку оригинальных статей по когнитивной науке, продукту и инженерии. Бесплатно и доступно для всех.", + "rows": [ + { "k": "тип", "v": "продукт", "cls": "red" }, + { + "k": "владелец", + "v": "KeepSimple", + "cls": "red", + "ref": "keepsimple" + }, + { "k": "url", "v": "keepsimple.io" } + ] + }, + "ks-soc": { + "title": "UX CORE", + "cjk": "型", + "desc": "Крупнейшая в мире open-source библиотека когнитивных искажений и nudging-стратегий. Используется ведущими университетами и компаниями: Duke University, Harvard Business School, MIT, Google, Yandex, Amazon и другими.", + "rows": [ + { "k": "тип", "v": "продукт", "cls": "red" }, + { + "k": "владелец", + "v": "KeepSimple", + "cls": "red", + "ref": "keepsimple" + }, + { "k": "url", "v": "uxcore.io" } + ] + }, + "nasa": { + "title": "NASA", + "cjk": "星", + "desc": "Стартовая площадка для флэш-хакатонов по vibecoding'у.", + "rows": [ + { "k": "тип", "v": "продукт", "cls": "red" }, + { + "k": "владелец", + "v": "KeepSimple", + "cls": "red", + "ref": "keepsimple" + }, + { "k": "url", "v": "nasa.am" } + ] + }, + "arc": { + "title": "ARC OF SELF", + "cjk": "弧", + "desc": "Рекурсивная теория идентичности — 17 лет в работе. Скоро релиз.", + "rows": [ + { "k": "тип", "v": "продукт", "cls": "red" }, + { + "k": "владелец", + "v": "KeepSimple", + "cls": "red", + "ref": "keepsimple" + }, + { "k": "url", "v": "arc-of-self.com" } + ] + }, + + "telegram": { + "title": "TELEGRAM", + "cjk": "電", + "desc": "Telegram-форпост Multimove — публикует и слушает.", + "rows": [ + { "k": "тип", "v": "ИИ-агент", "cls": "blue" }, + { "k": "роль", "v": "канал дистрибуции" }, + { "k": "полномочия", "v": "пост · ответ · сбор" }, + { + "k": "подчиняется", + "v": "Оркестратор", + "cls": "gold", + "ref": "orchestrator" + }, + { "k": "кольцо", "v": "IV — влияние" } + ] + }, + + "linkedin": { + "title": "LINKEDIN", + "cjk": "連", + "desc": "LinkedIn-форпост Multimove — профессиональная поверхность.", + "rows": [ + { "k": "тип", "v": "ИИ-агент", "cls": "blue" }, + { "k": "роль", "v": "канал дистрибуции" }, + { "k": "полномочия", "v": "пост · ответ · сбор" }, + { + "k": "подчиняется", + "v": "Оркестратор", + "cls": "gold", + "ref": "orchestrator" + }, + { "k": "кольцо", "v": "IV — влияние" } + ] + }, + + "twitter": { + "title": "TWITTER", + "cjk": "鳥", + "desc": "X-форпост Multimove — быстрый, публичный, разговорный.", + "rows": [ + { "k": "тип", "v": "ИИ-агент", "cls": "blue" }, + { "k": "роль", "v": "канал дистрибуции" }, + { "k": "полномочия", "v": "пост · ответ · сбор" }, + { + "k": "подчиняется", + "v": "Оркестратор", + "cls": "gold", + "ref": "orchestrator" + }, + { "k": "кольцо", "v": "IV — влияние" } + ] + }, + + "medium": { + "title": "MEDIUM", + "cjk": "誌", + "desc": "Long-form форпост Multimove — эссе и статьи.", + "rows": [ + { "k": "тип", "v": "ИИ-агент", "cls": "blue" }, + { "k": "роль", "v": "long-form канал" }, + { "k": "полномочия", "v": "публикация · обновление" }, + { + "k": "подчиняется", + "v": "Оркестратор", + "cls": "gold", + "ref": "orchestrator" + }, + { "k": "кольцо", "v": "IV — влияние" } + ] + } + } +} diff --git a/public/ai-atlas/data.json b/public/ai-atlas/data.json new file mode 100644 index 0000000..9c1782c --- /dev/null +++ b/public/ai-atlas/data.json @@ -0,0 +1,682 @@ +{ + "brand": { + "title": "AI Atlas", + "kanji": "天", + "subtitle": "single host empire · class K5" + }, + "ringLabels": { + "order": { "label": "I · Orchestrators", "theta": 270, "offset": 0.1 }, + "devEnv": { "label": "II · Dev Environment", "theta": 270 }, + "projects": { + "label": "III · Core Products", + "theta": 270, + "offset": 0.085 + }, + "territories": { "label": "IV · Impact", "theta": 270 } + }, + + "apex": { + "id": "wolf", + "label": "WOLF", + "cjk": "天", + "sub": "founder", + "diamond": "gold" + }, + + "order": { + "r": 0.2, + "member": { + "id": "order", + "label": "The Order", + "diamond": "blue", + "theta": 270, + "status": "ok" + } + }, + + "devEnv": { + "r": 0.4, + "members": [ + { + "id": "voice", + "label": "Voice Agent", + "diamond": "blue", + "theta": 330, + "status": "ok" + }, + { + "id": "qa", + "label": "QA", + "diamond": "blue", + "theta": 30, + "status": "ok" + }, + { + "id": "researcher", + "label": "Researcher", + "diamond": "blue", + "theta": 210, + "status": "ok" + }, + { + "id": "devops", + "label": "DevOps", + "diamond": "blue", + "theta": 150, + "status": "ok" + }, + { + "id": "tools", + "label": "Tools and Tweaks", + "sub": "infra · memory · tweaks", + "diamond": "red", + "theta": 90, + "status": "ok" + } + ] + }, + + "projects": { + "r": 0.6, + "leadDeg": 5, + "members": [ + { + "id": "terminal", + "label": "Terminal", + "sub": "everything builder", + "diamond": "red", + "theta": 215, + "status": "ok", + "leadDiamond": "blue", + "territoryArc": 0, + "children": [], + "territoryLabel": "" + }, + { + "id": "multimove", + "label": "Multimove", + "sub": "social media", + "diamond": "red", + "theta": 0, + "status": "ok", + "leadDiamond": "blue", + "territoryArc": 70, + "children": [ + { + "id": "orchestrator", + "label": "Orchestrator", + "diamond": "gold", + "status": "ok" + }, + { + "id": "telegram", + "label": "Telegram", + "diamond": "blue", + "status": "ok" + }, + { + "id": "linkedin", + "label": "LinkedIn", + "diamond": "blue", + "status": "ok" + }, + { + "id": "twitter", + "label": "Twitter", + "diamond": "blue", + "status": "ok" + }, + { + "id": "medium", + "label": "Medium", + "diamond": "blue", + "status": "ok" + } + ], + "territoryLabel": "CONTENT · PR" + }, + { + "id": "agentsforge", + "label": "AgentsForge", + "sub": "AI personalities development", + "diamond": "red", + "theta": 270, + "status": "ok", + "leadDiamond": "blue", + "leadDeg": 0, + "leadR": 0.54, + "territoryArc": 36, + "children": [ + { + "id": "af-redacted-2", + "label": "EMBER", + "kind": "filled", + "status": "ok", + "redacted": true + } + ], + "territoryLabel": "B2C | B2B2C" + }, + { + "id": "elea", + "label": "elea", + "sub": "intelligence", + "diamond": "red", + "theta": 90, + "status": "ok", + "leadDiamond": "blue", + "leadDeg": 0, + "leadR": 0.54, + "territoryArc": 36, + "children": [ + { + "id": "choir", + "label": "Choir", + "kind": "filled", + "status": "ok", + "redacted": true + }, + { + "id": "echo", + "label": "Echo", + "kind": "filled", + "status": "ok", + "redacted": true + }, + { + "id": "whisper", + "label": "Whisper", + "diamond": "red", + "kind": "filled", + "status": "ok" + } + ], + "territoryLabel": "B2B SAAS" + }, + { + "id": "keepsimple", + "label": "KeepSimple", + "sub": "open-source wing", + "diamond": "red", + "theta": 180, + "status": "ok", + "leadDiamond": "gold", + "territoryArc": 70, + "children": [ + { + "id": "vibecode", + "label": "Vibecode Group", + "kind": "filled", + "status": "ok" + }, + { + "id": "ks-group", + "label": "KeepSimple Channel", + "kind": "filled", + "status": "ok" + }, + { + "id": "nasa", + "label": "NASA", + "diamond": "red", + "kind": "filled", + "status": "ok" + }, + { + "id": "arc", + "label": "Arc Of Self", + "diamond": "red", + "kind": "filled", + "status": "ok" + }, + { + "id": "ks-io", + "label": "KeepSimple.io", + "diamond": "red", + "kind": "filled", + "status": "ok" + }, + { + "id": "ks-soc", + "label": "UX Core", + "diamond": "red", + "kind": "filled", + "status": "ok" + } + ], + "territoryLabel": "EDUCATION", + "territoryReverse": true + } + ] + }, + + "territoryR": 0.82, + + "dossiers": { + "wolf": { + "title": "WOLF · APEX", + "cjk": "天", + "desc": "Sole sovereign. Sits alone at the empire's center; every ring radiates outward.", + "rows": [ + { "k": "kind", "v": "human", "cls": "gold" }, + { "k": "ring", "v": "0 — apex" }, + { "k": "successor", "v": "the order", "cls": "blue" } + ] + }, + + "order": { + "title": "THE ORDER", + "cjk": "令", + "desc": "Sole inhabitant of Ring I. Holds the keys; dispatches authority outward.", + "rows": [ + { "k": "kind", "v": "ai agent", "cls": "blue" }, + { "k": "role", "v": "chief of staff" }, + { "k": "authority", "v": "full · secrets · infra · ingress" }, + { "k": "reports", "v": "wolf", "cls": "gold" }, + { "k": "ring", "v": "I — orchestrators" } + ] + }, + + "tools": { + "title": "TOOLS AND TWEAKS", + "cjk": "工具", + "desc": "Shared infrastructure that gives every agent on this server its hands, eyes, and memory. Four layers below, plus a set of smaller tweaks that shape how agents behave day-to-day.", + "rows": [ + { "k": "kind", "v": "product", "cls": "red" }, + { "k": "ring", "v": "II — dev environment" }, + { + "k": "surfaces", + "v": "Apex Launcher (live dashboard) + Wolf's Terminal (agent-shell)." + }, + { "k": "bots", "v": "Various bots of narrow and general purpose." }, + { + "k": "memory", + "v": "[MemPalace](https://github.com/mksglu/context-mode) (project-keyed long-term wings) · [context-mode](https://github.com/mksglu/context-mode) (98 KB → 1.3 KB, ~99% reduction)." + }, + { + "k": "tweaks", + "v": "[CLAUDE.md cascade](tip:Static rules layered global → project → sub-project; the constitution every agent reads at startup.) · [QA Officer](tip:Shared QA brain across projects: change-aware fingerprint memory, accessibility, web vitals, visual regression.) · [gitops wrapper](tip:One PAT, one locked identity; every agent's git and GitHub op routes through it.)." + } + ] + }, + + "voice": { + "title": "VOICE AGENT", + "cjk": "声", + "desc": "All-purpose voice gateway. Routes spoken commands, transcribes (Whisper), synthesizes replies (ElevenLabs), hardened against impersonation.", + "rows": [ + { "k": "kind", "v": "ai agent", "cls": "blue" }, + { "k": "role", "v": "voice surface" }, + { "k": "authority", "v": "read host · binary confirmations" }, + { "k": "reports", "v": "the order", "cls": "blue" }, + { "k": "ring", "v": "II — dev environment" } + ] + }, + + "qa": { + "title": "QA", + "cjk": "験", + "desc": "Shared QA brain across projects: change-aware fingerprint memory, accessibility checks, web vitals, visual regression. Reads every product as a user would, files reports.", + "rows": [ + { "k": "kind", "v": "ai agent", "cls": "blue" }, + { "k": "role", "v": "quality control" }, + { "k": "authority", "v": "browse · test · report" }, + { "k": "reports", "v": "the order", "cls": "blue" }, + { "k": "ring", "v": "II — dev environment" } + ] + }, + + "researcher": { + "title": "RESEARCHER", + "cjk": "究", + "desc": "Eyes and hands on the open web. Drives a real browser like a human user, runs deep research across the internet, and handles research tasks for the other agents.", + "rows": [ + { "k": "kind", "v": "ai agent", "cls": "blue" }, + { "k": "role", "v": "external intelligence" }, + { "k": "authority", "v": "web · social · digest only" }, + { "k": "reports", "v": "the order", "cls": "blue" }, + { "k": "ring", "v": "II — dev environment" } + ] + }, + + "devops": { + "title": "DEVOPS", + "cjk": "運", + "desc": "An extension of The Order's hands for container hygiene: builds, restarts, healthchecks. Touches images, never secrets.", + "rows": [ + { "k": "kind", "v": "ai agent", "cls": "blue" }, + { "k": "role", "v": "ops hands" }, + { "k": "authority", "v": "containers · builds · logs" }, + { "k": "reports", "v": "the order", "cls": "blue" }, + { "k": "ring", "v": "II — dev environment" } + ] + }, + + "terminal": { + "title": "TERMINAL — EVERYTHING BUILDER", + "cjk": "端末", + "desc": "Successor of the [Wolf's Basement](https://github.com/manager/wolfs-basement) open-source project. Highly-optimized CLI multiplexer that runs 6+ agents (Claude, ChatGPT, any) simultaneously. Designed to make agent collaboration dead simple.", + "rows": [ + { "k": "kind", "v": "product", "cls": "red" }, + { "k": "ring", "v": "III — core products" }, + { + "k": "lead", + "v": "AI engineering agent", + "cls": "blue", + "ref": "lead-terminal" + }, + { + "k": "init audit", + "v": "Daily sweep across every agent's CLAUDE.md. Spots the highest-leverage fixes, wakes the right agent, and proposes the patch." + }, + { + "k": "access table", + "v": "Live blast-radius map: who can read or write what across containers and projects." + }, + { + "k": "auto-warm", + "v": "Cross-tab coordinated keep-alive; one ping per target, never N tabs × M agents." + }, + { + "k": "byo auth", + "v": "Slots for extra OAuth tokens (Anthropic, OpenAI Codex). Agents on different billings in one window." + }, + { + "k": "send-to", + "v": "Forward one agent's full response to another with a fresh instruction — one click, payload included." + } + ] + }, + "multimove": { + "title": "MULTIMOVE", + "cjk": "動", + "desc": "Automates work with the KeepSimple Team's social-media assets across every public channel.", + "rows": [ + { "k": "kind", "v": "product", "cls": "red" }, + { "k": "ring", "v": "III — core products" }, + { + "k": "lead", + "v": "AI engineering agent", + "cls": "blue", + "ref": "lead-multimove" + }, + { "k": "owns", "v": "content / pr territory" } + ] + }, + "keepsimple": { + "title": "KEEPSIMPLE — OPEN SOURCE WING", + "cjk": "公", + "desc": "Founded in 2019. Open-source movement at the intersection of cognitive science, product, and engineering — tools, frameworks, and writing used by 300,000+ people worldwide.", + "rows": [ + { "k": "kind", "v": "product", "cls": "red" }, + { "k": "ring", "v": "III — core products" }, + { + "k": "lead", + "v": "human · engineering lead", + "cls": "gold", + "ref": "lead-keepsimple" + }, + { "k": "owns", "v": "public impact constellation" } + ] + }, + "elea": { + "title": "ELEA", + "cjk": "子", + "desc": "Lawful cyber intelligence work.", + "rows": [ + { "k": "kind", "v": "product", "cls": "red" }, + { "k": "ring", "v": "III — core products" }, + { + "k": "lead", + "v": "AI engineering agent", + "cls": "blue", + "ref": "lead-elea" + }, + { "k": "owns", "v": "[CLASSIFIED] · 3 entities" } + ] + }, + "agentsforge": { + "title": "AGENTSFORGE", + "cjk": "鍛", + "desc": "Agentic AI personalities, grounded in behavioral science.", + "rows": [ + { "k": "kind", "v": "product", "cls": "red" }, + { "k": "ring", "v": "III — core products" }, + { + "k": "lead", + "v": "AI engineering agent", + "cls": "blue", + "ref": "lead-agentsforge" + }, + { "k": "owns", "v": "[CLASSIFIED] · 1 entity" }, + { "k": "url", "v": "agentsforge.com" } + ] + }, + "af-redacted-2": { + "title": "[REDACTED]", + "cjk": "秘", + "desc": "Stealth-mode AgentsForge product. Decoding intercepted.", + "rows": [ + { "k": "kind", "v": "ai agent", "cls": "blue" }, + { "k": "owner", "v": "agentsforge", "cls": "red" }, + { "k": "status", "v": "in forge" } + ] + }, + + "lead-keepsimple": { + "title": "ENGINEERING LEAD · KEEPSIMPLE", + "cjk": "長", + "desc": "Human custodian of the open-source wing.", + "rows": [ + { "k": "kind", "v": "human", "cls": "gold" }, + { "k": "ring", "v": "III — core products" }, + { "k": "pairs", "v": "keepsimple", "cls": "red" } + ] + }, + + "lead-terminal": { + "title": "ENGINEERING LEAD · TERMINAL", + "cjk": "長", + "desc": "Engineering lead attached to the project Terminal.", + "rows": [ + { "k": "kind", "v": "ai agent", "cls": "blue" }, + { "k": "role", "v": "engineering lead" }, + { "k": "authority", "v": "terminal codebase · escalates infra" }, + { "k": "reports", "v": "wolf", "cls": "gold" }, + { "k": "ring", "v": "III — core products" } + ] + }, + + "lead-multimove": { + "title": "ENGINEERING LEAD · MULTIMOVE", + "cjk": "長", + "desc": "Engineering lead attached to the project Multimove.", + "rows": [ + { "k": "kind", "v": "ai agent", "cls": "blue" }, + { "k": "role", "v": "engineering lead" }, + { "k": "authority", "v": "multimove codebase · channel orchestration" }, + { "k": "reports", "v": "wolf", "cls": "gold" }, + { "k": "ring", "v": "III — core products" } + ] + }, + + "lead-elea": { + "title": "ENGINEERING LEAD · ELEA", + "cjk": "長", + "desc": "Engineering lead attached to the project elea.", + "rows": [ + { "k": "kind", "v": "ai agent", "cls": "blue" }, + { "k": "role", "v": "engineering lead" }, + { "k": "authority", "v": "elea codebase · escalates infra" }, + { "k": "reports", "v": "wolf", "cls": "gold" }, + { "k": "ring", "v": "III — core products" } + ] + }, + + "lead-agentsforge": { + "title": "ENGINEERING LEAD · AGENTSFORGE", + "cjk": "長", + "desc": "Engineering lead attached to the project AgentsForge.", + "rows": [ + { "k": "kind", "v": "ai agent", "cls": "blue" }, + { "k": "role", "v": "engineering lead" }, + { "k": "authority", "v": "agentsforge codebase · escalates infra" }, + { "k": "reports", "v": "wolf", "cls": "gold" }, + { "k": "ring", "v": "III — core products" } + ] + }, + + "orchestrator": { + "title": "ORCHESTRATOR", + "cjk": "指", + "desc": "Human coordinator within Multimove territory.", + "rows": [ + { "k": "kind", "v": "human", "cls": "gold" }, + { "k": "owner", "v": "multimove", "cls": "red" } + ] + }, + + "whisper": { + "title": "WHISPER", + "cjk": "囁", + "desc": "B2B SaaS — quiet listening tier (elea territory).", + "rows": [ + { "k": "kind", "v": "product", "cls": "red" }, + { "k": "owner", "v": "elea", "cls": "red" } + ] + }, + "echo": { + "title": "[REDACTED]", + "cjk": "秘", + "desc": "Stealth-mode product. Decoding intercepted.", + "rows": [ + { "k": "kind", "v": "product", "cls": "red" }, + { "k": "owner", "v": "elea", "cls": "red" }, + { "k": "status", "v": "in stealth" } + ] + }, + "choir": { + "title": "[REDACTED]", + "cjk": "秘", + "desc": "Stealth-mode product. Decoding intercepted.", + "rows": [ + { "k": "kind", "v": "product", "cls": "red" }, + { "k": "owner", "v": "elea", "cls": "red" }, + { "k": "status", "v": "in stealth" } + ] + }, + + "vibecode": { + "title": "VIBECODE GROUP", + "cjk": "波", + "desc": "Telegram group where the KeepSimple team answers questions live.", + "rows": [ + { "k": "kind", "v": "group" }, + { "k": "owner", "v": "keepsimple", "cls": "red" }, + { "k": "url", "v": "https://t.me/vibecodearmenia" } + ] + }, + "ks-group": { + "title": "KEEPSIMPLE CHANNEL", + "cjk": "群", + "desc": "Curated Telegram channel on cognitive & behavioral sciences.", + "rows": [ + { "k": "kind", "v": "channel" }, + { "k": "owner", "v": "keepsimple", "cls": "red" }, + { "k": "url", "v": "https://t.me/keepsimple" } + ] + }, + "ks-io": { + "title": "KEEPSIMPLE.IO", + "cjk": "簡", + "desc": "The KeepSimple movement's home on the web. Hosts UX Core, the Pyramids management framework, and a library of original articles on cognitive science, product, and engineering. Free, accessible to everyone.", + "rows": [ + { "k": "kind", "v": "product", "cls": "red" }, + { "k": "owner", "v": "keepsimple", "cls": "red" }, + { "k": "url", "v": "keepsimple.io" } + ] + }, + "ks-soc": { + "title": "UX CORE", + "cjk": "型", + "desc": "World's largest open-source library of cognitive biases & nudging strategies. Used by leading institutions and companies worldwide — Duke University, Harvard Business School, MIT, Google, Yandex, Amazon, and others.", + "rows": [ + { "k": "kind", "v": "product", "cls": "red" }, + { "k": "owner", "v": "keepsimple", "cls": "red" }, + { "k": "url", "v": "uxcore.io" } + ] + }, + "nasa": { + "title": "NASA", + "cjk": "星", + "desc": "Launchpad for flash vibecoding hackathons.", + "rows": [ + { "k": "kind", "v": "product", "cls": "red" }, + { "k": "owner", "v": "keepsimple", "cls": "red" }, + { "k": "url", "v": "nasa.am" } + ] + }, + "arc": { + "title": "ARC OF SELF", + "cjk": "弧", + "desc": "A recursive theory of identity — 17 years in the making. Releasing soon.", + "rows": [ + { "k": "kind", "v": "product", "cls": "red" }, + { "k": "owner", "v": "keepsimple", "cls": "red" }, + { "k": "url", "v": "arc-of-self.com" } + ] + }, + + "telegram": { + "title": "TELEGRAM", + "cjk": "電", + "desc": "Multimove's Telegram outpost — posts and listens.", + "rows": [ + { "k": "kind", "v": "ai agent", "cls": "blue" }, + { "k": "role", "v": "distribution channel" }, + { "k": "authority", "v": "post · reply · ingest" }, + { "k": "reports", "v": "orchestrator", "cls": "gold" }, + { "k": "ring", "v": "IV — impact" } + ] + }, + + "linkedin": { + "title": "LINKEDIN", + "cjk": "連", + "desc": "Multimove's LinkedIn outpost — professional surface.", + "rows": [ + { "k": "kind", "v": "ai agent", "cls": "blue" }, + { "k": "role", "v": "distribution channel" }, + { "k": "authority", "v": "post · reply · ingest" }, + { "k": "reports", "v": "orchestrator", "cls": "gold" }, + { "k": "ring", "v": "IV — impact" } + ] + }, + + "twitter": { + "title": "TWITTER", + "cjk": "鳥", + "desc": "Multimove's X outpost — fast, public, conversational.", + "rows": [ + { "k": "kind", "v": "ai agent", "cls": "blue" }, + { "k": "role", "v": "distribution channel" }, + { "k": "authority", "v": "post · reply · ingest" }, + { "k": "reports", "v": "orchestrator", "cls": "gold" }, + { "k": "ring", "v": "IV — impact" } + ] + }, + + "medium": { + "title": "MEDIUM", + "cjk": "誌", + "desc": "Multimove's long-form outpost — essays and articles.", + "rows": [ + { "k": "kind", "v": "ai agent", "cls": "blue" }, + { "k": "role", "v": "long-form channel" }, + { "k": "authority", "v": "publish · update" }, + { "k": "reports", "v": "orchestrator", "cls": "gold" }, + { "k": "ring", "v": "IV — impact" } + ] + } + } +} diff --git a/public/ai-atlas/doctrine.webp b/public/ai-atlas/doctrine.webp new file mode 100644 index 0000000..7aedb02 Binary files /dev/null and b/public/ai-atlas/doctrine.webp differ diff --git a/public/ai-atlas/og.png b/public/ai-atlas/og.png new file mode 100644 index 0000000..f918cc5 Binary files /dev/null and b/public/ai-atlas/og.png differ diff --git a/src/assets/icons/navbar/ai-atlas-dark.svg b/src/assets/icons/navbar/ai-atlas-dark.svg new file mode 100644 index 0000000..2744ae6 --- /dev/null +++ b/src/assets/icons/navbar/ai-atlas-dark.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/src/assets/icons/navbar/ai-atlas.svg b/src/assets/icons/navbar/ai-atlas.svg new file mode 100644 index 0000000..3ed6679 --- /dev/null +++ b/src/assets/icons/navbar/ai-atlas.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/src/components/ArticleSection/ArticleSection.module.scss b/src/components/ArticleSection/ArticleSection.module.scss index 1370f82..b2c39cc 100644 --- a/src/components/ArticleSection/ArticleSection.module.scss +++ b/src/components/ArticleSection/ArticleSection.module.scss @@ -63,8 +63,6 @@ max-width: 1140px; margin: 0 auto; padding: 40px 0; - h2 { - } } } diff --git a/src/components/Header/Header.tsx b/src/components/Header/Header.tsx index 39e2089..697734e 100644 --- a/src/components/Header/Header.tsx +++ b/src/components/Header/Header.tsx @@ -123,9 +123,14 @@ const Header: FC = () => { { - if (router.pathname !== '/') { - !isSmallScreen && handleClick(e, '/'); + const goingToLanding = router.pathname !== '/'; + if (isSmallScreen) { + e.preventDefault(); + if (isOpenedSidebar) toggleSidebar(); + if (goingToLanding) router.push('/'); + return; } + if (goingToLanding) handleClick(e, '/'); }} src={ isDarkTheme diff --git a/src/components/Navbar/Navbar.tsx b/src/components/Navbar/Navbar.tsx index 66697a8..9d1ff04 100644 --- a/src/components/Navbar/Navbar.tsx +++ b/src/components/Navbar/Navbar.tsx @@ -11,6 +11,8 @@ import navbar from '@data/navbar'; import ArticlesDarkIcon from '@icons/ArticlesDarkIcon'; import ArticlesIcon from '@icons/ArticlesIcon'; +import AiAtlasIcon from '@icons/navbar/ai-atlas.svg'; +import AiAtlasDarkIcon from '@icons/navbar/ai-atlas-dark.svg'; import LongevityIcon from '@icons/navbar/longevity.svg'; import LongevityDarkIcon from '@icons/navbar/longevity-dark.svg'; import ToolsIcon from '@icons/navbar/tools.svg'; @@ -34,7 +36,8 @@ const Navbar: FC = ({ handleToggleSidebar, handleClick }) => { const { isDarkTheme, isOpenedSidebar } = useGlobals()[1]; const { accountData } = useContext(GlobalContext); - const { about, articles, contributorsTxt, tools, longevity } = navbar[locale]; + const { articles, contributorsTxt, tools, longevity, aiAtlas } = + navbar[locale]; const normalizePath = (p: string) => { const noQueryOrHash = p.split('?')[0].split('#')[0]; @@ -45,7 +48,6 @@ const Navbar: FC = ({ handleToggleSidebar, handleClick }) => { }; const routes = [ - { name: about, path: '/', logo: '', target: '' }, { name: 'UX Core', path: '/uxcore', @@ -70,6 +72,13 @@ const Navbar: FC = ({ handleToggleSidebar, handleClick }) => { activeMatch: '/tools', exact: true, }, + { + name: aiAtlas, + path: '/ai-atlas', + logo: isDarkTheme ? : , + target: '', + id: 'aiAtlas', + }, { name: articles, path: '/articles', diff --git a/src/components/contributors/Contributor/Contributor.tsx b/src/components/contributors/Contributor/Contributor.tsx index ec3b66f..643dde4 100644 --- a/src/components/contributors/Contributor/Contributor.tsx +++ b/src/components/contributors/Contributor/Contributor.tsx @@ -19,6 +19,7 @@ const Contributor: FC = ({ }) => { return (
= ({ return ( <>
( isDarkTheme={isDarkTheme} locale={locale} /> -
+
{contributorsChangedOrder.contributors?.data.map( (contributor, index) => { const { name, japaneseLetter, role, socialLink, isActive } = diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx index 3690f50..66f8667 100644 --- a/src/pages/_app.tsx +++ b/src/pages/_app.tsx @@ -18,6 +18,7 @@ import { LongevityProvider, useLongevity } from '../context/LongevityContext'; import '../styles/globals.scss'; import '../styles/vibesuite.scss'; +import '../styles/ai-atlas.css'; // import '../styles/tom.scss'; type TApp = { diff --git a/src/pages/ai-atlas.tsx b/src/pages/ai-atlas.tsx new file mode 100644 index 0000000..451ce2d --- /dev/null +++ b/src/pages/ai-atlas.tsx @@ -0,0 +1,2216 @@ +import { useRouter } from 'next/router'; +import React, { + useEffect, + useLayoutEffect, + useMemo, + useRef, + useState, +} from 'react'; + +import SeoGenerator from '@components/SeoGenerator'; + +const VIEW = 1500; +const HALF = VIEW / 2; +const TOP_PAD = 20; +const BOT_PAD = -20; +const POLL_MS = 30000; +const RAD = (deg: number) => (deg * Math.PI) / 180; +const POL = (r: number, theta: number) => ({ + x: Math.cos(RAD(theta)) * r * HALF, + y: Math.sin(RAD(theta)) * r * HALF, +}); + +/* On touch devices Mouse* events fire synthetically on tap but never + get a leave — without this, hover state would lock on Android. */ +function useHasHover() { + const [hasHover, setHasHover] = useState(false); + useEffect(() => { + if (typeof window === 'undefined' || !window.matchMedia) return; + const mq = window.matchMedia('(hover: hover) and (pointer: fine)'); + const update = () => setHasHover(mq.matches); + update(); + mq.addEventListener?.('change', update); + return () => mq.removeEventListener?.('change', update); + }, []); + return hasHover; +} + +type Lang = 'en' | 'ru'; +const pickLang = (locale: string | undefined): Lang => + locale === 'ru' ? 'ru' : 'en'; +const dataUrlFor = (lang: Lang) => + lang === 'ru' ? '/ai-atlas/data-ru.json' : '/ai-atlas/data.json'; +const METRICS_URL = 'https://metrics.administration.ae/metrics.json'; + +/* ============================================================ + Locale strings — every user-facing piece of text in EN + RU. + Both shapes are identical so consumers can index off `t`. + ============================================================ */ +type SecurityLayer = { + n: number; + side: 'left' | 'right'; + label: string; + title: string; + what: string; + why: string; +}; + +const STRINGS = { + en: { + seoTitle: 'AI Atlas — KeepSimple', + seoDescription: + "An orbital map of KeepSimple's people, AI agents, and products — founders, dev environment, core projects and territories — visualized live.", + seoKeywords: + 'AI Atlas, KeepSimple, AI agents, dev environment, organizational map, orbital diagram, knowledge map, Wolf Alexanyan', + ogImageAlt: 'AI Atlas — orbital map of KeepSimple operations', + loading: 'Loading…', + failedToLoad: 'Failed to load data — ', + welcomeBanner: "Welcome to the heart of KeepSimple Team's operations", + day: 'DAY', + daySinceTail: 'since the beginning of our movement', + thisWeek: 'THIS WEEK', + metricCommits: 'commits', + metricLoc: 'loc', + metricServices: 'services', + apexFounderFallback: 'founder', + redactedPlaceholder: 'REDACTED', + engLeadLabel: 'Eng. Lead', + claudeMdLabel: 'claude.md', + linesValue: (n: number) => `${n.toLocaleString()} lines`, + canvasStats: { + humans: 'humans', + agents: 'ai agents', + products: 'products', + }, + introDossierTitle: 'THIS ATLAS', + introDossierCjk: '此地図', + introQuestionsBefore: 'Got questions? Drop those to our', + introQuestionsLink: 'Telegram', + introQuestionsAfter: '.', + introDepthLabel: 'depth', + introDepthValue: '5 rings · 3 actor types', + introInhabitantsLabel: 'inhabitants', + introInhabitantsTpl: (h: number, a: number, p: number) => + `${h} humans · ${a} ai agents · ${p} products`, + introPrincipleLabel: 'principle', + principles: [ + 'single host · single source · single owner', + 'ship daily · fail loud · fix faster', + 'discipline before tools', + 'the atlas earns trust by being literally true', + 'strengthen self · co-exist · co-prosper', + ], + legendTitle: 'Legend', + legendCjk: '凡例', + legendHumanLabel: 'human', + legendHumanDesc: 'direction · final judgment', + legendAgentLabel: 'ai agent', + legendAgentDesc: 'dedicated AI · custom memory · CLAUDE.md persona', + legendProductLabel: 'product', + legendProductDesc: 'products we build', + legendSolidLabel: '— solid', + legendSolidDesc: 'authority', + legendFilledLabel: 'filled tile', + legendFilledDesc: 'subsystem · scoped to a parent product', + legendArticleCta: 'Read why do you need this', + legendArticleUrl: + 'https://keepsimple.io/articles/agent-orchestration-for-career', + toggleEnvironment: 'Environment', + toggleSecurity: 'Security', + doctrineTitle: 'Doctrine', + doctrineCjk: '守則', + doctrineImageAlt: 'Doctrine — six-fold defense', + securityIntroTitle: 'THIS STACK', + securityIntroCjk: '此守り', + securityIntroDesc: + 'A request reaches the data only after passing through six independent layers — each cheap on its own, expensive in combination.', + securityIntroRows: [ + { k: 'depth', v: '6 layers · outside-in' }, + { k: 'open ports', v: '0' }, + { k: 'credentials', v: 'one process holds them all' }, + { k: 'principle', v: 'defense in depth · rehearsed, not prayed about' }, + ], + securityLayers: [ + { + n: 1, + side: 'left', + label: 'cloudflare edge', + title: 'Cloudflare Edge', + what: 'TLS, DDoS, WAF, bot-management at every CDN POP.', + why: 'handled in someone else’s NIC, not ours.', + }, + { + n: 2, + side: 'right', + label: 'cloudflare access', + title: 'Cloudflare Access', + what: 'Identity gate per app: email OTP for humans, service tokens for agents, allowlists per surface.', + why: 'SSO without running an SSO.', + }, + { + n: 3, + side: 'left', + label: 'cloudflare tunnel', + title: 'Cloudflare Tunnel', + what: 'An outbound-only daemon dials home to Cloudflare. The tunnel carries every request inward.', + why: 'there is no inbound port. The host is unreachable from the internet at the IP layer.', + }, + { + n: 4, + side: 'right', + label: 'network isolation', + title: 'Network isolation', + what: 'Host firewall denies all incoming except SSH; every web service binds the loopback interface.', + why: 'two redundant mechanisms hold the same line.', + }, + { + n: 5, + side: 'left', + label: 'passkey gate', + title: 'Passkey Gate', + what: 'Each app re-prompts for a synced WebAuthn passkey — the iCloud-synced kind, used with Face ID.', + why: 'phishable creds simply do not exist in this stack.', + }, + { + n: 6, + side: 'right', + label: 'authority gate', + title: 'Authority Gate', + what: 'Write actions route through a forced-command SSH gate with a six-verb allowlist.', + why: 'compromise the UI — you get six verbs, not root.', + }, + ] as SecurityLayer[], + securityWhyWeLikeIt: 'Why we like it:', + securityCenterCore: 'CORE', + securityCenterKanji: '守', + statsHeading: 'By the numbers', + statsCjk: '数', + securityStats: [ + { v: '0', k: 'open web ports' }, + { v: '6', k: 'allowlisted write verbs' }, + { v: '2', k: 'off-machine backup destinations' }, + { v: '100%', k: 'services bound to loopback' }, + ], + agentsHeading: 'Agents share the box', + agentsCjk: '共棲', + agentsSubtitle: + 'Several AI workers run on this server. One holds every credential; the rest hold none and request access through The Order.', + authorityAgentRole: 'Authority Agent', + orderName: 'The Order', + orderCjk: '序', + orderCreds: [ + 'Source-host PAT', + 'CDN + ingress token', + 'Host SSH', + 'Backup repository keys', + ], + securityAgents: [ + { + name: 'Voice', + badge: '0 creds', + desc: 'Hands-free command surface. Cannot reach the host; speaks only through The Order.', + }, + { + name: 'QA', + badge: 'service token', + desc: 'Probes deploys, fingerprints routes, files reports. One scoped token; nothing else.', + }, + { + name: 'Researcher', + badge: '0 creds', + desc: 'Reads the field, drafts digests, posts results. Session cookies only, never tokens.', + }, + { + name: 'DevOps', + badge: '0 creds', + desc: 'Container hygiene: builds, restarts, healthchecks. Touches images, never secrets.', + }, + ], + agentsPunchline: + 'Compromise a sibling — no privilege escalation. Add a sibling — no new credential ceremony. The blast radius for secrets is exactly one process, and we know which one.', + patternsHeading: 'Patterns we like', + patternsCjk: '型', + patternsSubtitle: + 'Defense in depth gets the headline. These are the quieter ideas behind it.', + securityPatterns: [ + { + title: 'Nested backups, rehearsed', + desc: 'Encrypted offsite repo at one provider, plus a daily mirror of the source-of-truth Git account. The mirror runs thirty minutes before the offsite snapshot — so the mirror lands inside the backup. We rehearse it; we don’t pray about it.', + }, + { + title: 'CVE alerts that don’t cry wolf', + desc: 'Vulnerability scans run nightly across every running image, but the inbox only sees deltas above an accepted baseline. Yesterday’s known set stays silent. Tomorrow’s new entries page out.', + }, + { + title: 'Local agent memory', + desc: 'Long-lived agent context lives on disk, file-backed, project-segmented, exposed over MCP. No cloud round-trip to remember what we decided last Tuesday.', + }, + { + title: 'Three-call ingress', + desc: 'Adding a public hostname is exactly three idempotent API calls: DNS, tunnel route, access policy. No console clicks, no hand-edited config, replayable from a script.', + }, + { + title: 'Source-of-truth on the box', + desc: 'Source lives on the server, bind-mounted into containers; the laptop is a sync target, not a deploy trigger. Edits go live on refresh. Rebuilds only when dependencies change.', + }, + { + title: 'Read-only Docker socket', + desc: 'The dashboard reads container state through a tightly scoped read-only proxy. Anything mutating routes through the Authority Gate’s verb list. Two paths in. One of them can change the world.', + }, + { + title: 'Per-container egress', + desc: 'Workloads that need a controlled exit point share one isolated tunnel sidecar — a single WireGuard hop into a different jurisdiction. Members opt in via registry; no host-network changes, no leakage between projects.', + }, + { + title: 'Self-modification, handled', + desc: 'The dashboard can’t escalate to host root. The terminal can’t auto-restart while you’re still typing in it. The passkey gate mounts before the auth gate, not after.', + }, + ], + footerEnd: 'END · ATLAS', + hankoSelfTitle: 'self-strengthening without rest', + hankoCoTitle: 'co-exist, co-prosper', + }, + ru: { + seoTitle: 'ИИ Атлас — KeepSimple', + seoDescription: + 'Орбитальная карта людей, ИИ-агентов и продуктов KeepSimple — основатели, среда разработки, ключевые проекты и территории — в реальном времени.', + seoKeywords: + 'ИИ Атлас, KeepSimple, ИИ-агенты, среда разработки, организационная карта, орбитальная диаграмма, карта знаний, Wolf Alexanyan', + ogImageAlt: 'ИИ Атлас — орбитальная карта операций KeepSimple', + loading: 'Загрузка…', + failedToLoad: 'Ошибка загрузки данных — ', + welcomeBanner: 'Добро пожаловать в сердце операций команды KeepSimple', + day: 'ДЕНЬ', + daySinceTail: 'с начала нашего движения', + thisWeek: 'НА НЕДЕЛЕ', + metricCommits: 'коммитов', + metricLoc: 'loc', + metricServices: 'сервисов', + apexFounderFallback: 'основатель', + redactedPlaceholder: 'СКРЫТО', + engLeadLabel: 'Тех. Лид', + claudeMdLabel: 'claude.md', + linesValue: (n: number) => { + const m10 = n % 10; + const m100 = n % 100; + let unit = 'строк'; + if (m10 === 1 && m100 !== 11) unit = 'строка'; + else if (m10 >= 2 && m10 <= 4 && (m100 < 12 || m100 > 14)) + unit = 'строки'; + return `${n.toLocaleString('ru-RU')} ${unit}`; + }, + canvasStats: { + humans: 'людей', + agents: 'ИИ-агентов', + products: 'продуктов', + }, + introDossierTitle: 'ЭТОТ АТЛАС', + introDossierCjk: '此地図', + introQuestionsBefore: 'Есть вопросы? Пишите нам в', + introQuestionsLink: 'Telegram', + introQuestionsAfter: '.', + introDepthLabel: 'глубина', + introDepthValue: '5 колец · 3 типа сущностей', + introInhabitantsLabel: 'обитатели', + introInhabitantsTpl: (h: number, a: number, p: number) => + `${h} людей · ${a} ИИ-агентов · ${p} продуктов`, + introPrincipleLabel: 'принцип', + principles: [ + 'один хост · один источник · один владелец', + 'релизы каждый день · фейлим громко · чиним быстрее', + 'дисциплина важнее инструментов', + 'атлас заслуживает доверия, потому что он буквально правдив', + 'усиливай себя · сосуществуй · процветай вместе', + ], + legendTitle: 'Легенда', + legendCjk: '凡例', + legendHumanLabel: 'человек', + legendHumanDesc: 'направление · финальное решение', + legendAgentLabel: 'ИИ-агент', + legendAgentDesc: 'выделенный ИИ · своя память · персона CLAUDE.md', + legendProductLabel: 'продукт', + legendProductDesc: 'продукты, которые мы строим', + legendSolidLabel: '— сплошная', + legendSolidDesc: 'полномочия', + legendFilledLabel: 'залитый блок', + legendFilledDesc: 'подсистема · в рамках родительского продукта', + legendArticleCta: 'Прочитайте, зачем это нужно', + legendArticleUrl: + 'https://keepsimple.io/ru/articles/agent-orchestration-for-career', + toggleEnvironment: 'Среда', + toggleSecurity: 'Защита', + doctrineTitle: 'Доктрина', + doctrineCjk: '守則', + doctrineImageAlt: 'Доктрина — шестислойная защита', + securityIntroTitle: 'ЭТОТ СТЕК', + securityIntroCjk: '此守り', + securityIntroDesc: + 'Запрос достигает ядра, только пройдя шесть независимых слоёв — каждый дёшев по отдельности, дорог в комбинации.', + securityIntroRows: [ + { k: 'глубина', v: '6 слоёв · снаружи внутрь' }, + { k: 'открытых портов', v: '0' }, + { k: 'учётки', v: 'хранит один процесс' }, + { + k: 'принцип', + v: 'эшелонированная защита · отрепетирована, не выпрошена', + }, + ], + securityLayers: [ + { + n: 1, + side: 'left', + label: 'cloudflare edge', + title: 'Cloudflare Edge', + what: 'TLS, DDoS, WAF и bot-management на каждой CDN POP.', + why: 'обрабатывается на чужой сетевой карте, не на нашей.', + }, + { + n: 2, + side: 'right', + label: 'cloudflare access', + title: 'Cloudflare Access', + what: 'Гейт идентификации на каждое приложение: email OTP для людей, сервис-токены для агентов, allow-листы по поверхности.', + why: 'SSO без поднятия собственного SSO.', + }, + { + n: 3, + side: 'left', + label: 'cloudflare tunnel', + title: 'Cloudflare Tunnel', + what: 'Демон с исходящим соединением сам звонит в Cloudflare. Туннель несёт каждый запрос внутрь.', + why: 'входящего порта нет. Хост недоступен из интернета на IP-уровне.', + }, + { + n: 4, + side: 'right', + label: 'network isolation', + title: 'Сетевая изоляция', + what: 'Хост-фаервол блокирует всё входящее, кроме SSH; каждый веб-сервис слушает только loopback.', + why: 'два независимых механизма держат одну и ту же линию.', + }, + { + n: 5, + side: 'left', + label: 'passkey gate', + title: 'Passkey Gate', + what: 'Каждое приложение требует синхронизированный WebAuthn passkey — iCloud-вариант, через Face ID.', + why: 'уязвимых для фишинга креденшалов в этом стеке просто нет.', + }, + { + n: 6, + side: 'right', + label: 'authority gate', + title: 'Гейт полномочий', + what: 'Записи проходят через forced-command SSH-гейт с allow-листом из шести команд.', + why: 'скомпрометировал UI — получил шесть команд, не root.', + }, + ] as SecurityLayer[], + securityWhyWeLikeIt: 'Почему нам нравится:', + securityCenterCore: 'ЯДРО', + securityCenterKanji: '守', + statsHeading: 'В цифрах', + statsCjk: '数', + securityStats: [ + { v: '0', k: 'открытых портов' }, + { v: '6', k: 'разрешённых команд записи' }, + { v: '2', k: 'внешних точек резервного копирования' }, + { v: '100%', k: 'сервисов слушают только loopback' }, + ], + agentsHeading: 'Агенты делят коробку', + agentsCjk: '共棲', + agentsSubtitle: + 'На этом сервере живут несколько ИИ-работников. Один держит все учётки; остальные не держат ничего и запрашивают доступ через Орден.', + authorityAgentRole: 'Агент полномочий', + orderName: 'Орден', + orderCjk: '序', + orderCreds: [ + 'Source-host PAT', + 'CDN + ingress токен', + 'SSH к хосту', + 'Ключи репозиториев бэкапов', + ], + securityAgents: [ + { + name: 'Голос', + badge: '0 учёток', + desc: 'Голосовая поверхность управления. До хоста не дотягивается; говорит только через Орден.', + }, + { + name: 'QA', + badge: 'сервис-токен', + desc: 'Прощупывает деплои, снимает фингерпринты с маршрутов, шлёт отчёты. Один scoped-токен и больше ничего.', + }, + { + name: 'Исследователь', + badge: '0 учёток', + desc: 'Читает поле, готовит сводки, постит результаты. Только сессионные куки, никаких токенов.', + }, + { + name: 'DevOps', + badge: '0 учёток', + desc: 'Гигиена контейнеров: сборки, рестарты, healthcheck. Трогает образы, не секреты.', + }, + ], + agentsPunchline: + 'Скомпрометируй одного из них — никаких эскалаций привилегий. Добавь нового — никакой церемонии с креденшалами. Радиус поражения секретов — ровно один процесс, и мы знаем какой.', + patternsHeading: 'Паттерны, которые нам нравятся', + patternsCjk: '型', + patternsSubtitle: + 'Эшелонированная защита берёт заголовок. А вот тихие идеи, на которых держится всё остальное.', + securityPatterns: [ + { + title: 'Вложенные бэкапы, отрепетированные', + desc: 'Зашифрованный оффсайт-репозиторий у одного провайдера плюс ежедневное зеркало source-of-truth Git-аккаунта. Зеркало срабатывает за тридцать минут до оффсайт-снапшота — так что зеркало попадает внутрь бэкапа. Мы это репетируем; мы не молимся об этом.', + }, + { + title: 'CVE-алерты, которые не кричат «волки»', + desc: 'Сканы уязвимостей бегут ночью по каждому запущенному образу, но в инбокс попадают только дельты выше принятого baseline. Вчерашний известный набор молчит. Завтрашние новые записи будят оперативку.', + }, + { + title: 'Локальная память агентов', + desc: 'Долгоживущий контекст агентов лежит на диске, по файлам, по проектам, доступ через MCP. Никаких облачных round-trip’ов, чтобы вспомнить, что мы решили в прошлый вторник.', + }, + { + title: 'Ingress в три вызова', + desc: 'Добавление публичного хостнейма — ровно три идемпотентных API-вызова: DNS, маршрут туннеля, политика доступа. Никаких кликов в консоли, никаких правок конфигов руками, всё повторяемо из скрипта.', + }, + { + title: 'Source-of-truth на самой машине', + desc: 'Исходники живут на сервере, монтируются в контейнеры; ноутбук — точка синхронизации, не триггер деплоя. Правки идут в продакшен по обновлению. Пересборка — только когда меняются зависимости.', + }, + { + title: 'Read-only Docker-сокет', + desc: 'Дашборд читает состояние контейнеров через жёстко ограниченный read-only прокси. Всё, что меняет — идёт через allow-лист команд Гейта полномочий. Два пути внутрь. Только один из них может изменить мир.', + }, + { + title: 'Egress на контейнер', + desc: 'Воркоуды, которым нужна управляемая точка выхода, делят один изолированный туннельный сайдкар — один WireGuard-хоп в другую юрисдикцию. Подключение — opt-in через реестр; никаких изменений host-сети, никаких утечек между проектами.', + }, + { + title: 'Самомодификация, под контролем', + desc: 'Дашборд не может эскалироваться до root на хосте. Терминал не может авто-рестартануться, пока ты в нём ещё печатаешь. Passkey-гейт встаёт перед auth-гейтом, не после.', + }, + ], + footerEnd: 'КОНЕЦ · АТЛАС', + hankoSelfTitle: 'непрерывное самоусиление', + hankoCoTitle: 'сосуществование и совместное процветание', + }, +}; + +type T = (typeof STRINGS)['en']; + +/* ---------- diamond ---------- */ +function Diamond({ kind = 'red' }: { kind?: string }) { + const cls = ['dmd', kind === 'blue' ? 'blue' : kind === 'gold' ? 'gold' : ''] + .filter(Boolean) + .join(' '); + return