18 KiB
name, description
| name | description |
|---|---|
| planet-rules | Planet repository rules split into LLM-loadable modules. |
Planet Rules
These rules are mandatory. If a requested action conflicts with this file, stop and report the conflict.
Loading Protocol
Read this top section first, then load only the modules relevant to the task.
Always load:
coresecurityworkflow
Load selectively:
| Module | Load when |
|---|---|
docs |
Writing, translating, linking, or publishing documentation |
uiux |
Visual design, layout, interaction, accessibility, responsive behavior |
frontend |
React, TypeScript, CSS, Vite, Bun, admin console, docs UI |
backend |
FastAPI, SQLAlchemy, data collectors, database, API performance |
earth |
3D Earth, canvas/Three.js, BGP/vessel/satellite/cable layers, map icons |
ai |
AI Provider, LLM gateway, prompts, model config, AI Playground |
release |
Version bumps, changelog, version history, commit/tag/push release work |
Do not load the entire file by default for small tasks. Use rg -n "^## Module:" rules.md to find module boundaries, then read only the needed block.
Module: core
Load When
Always.
Must
- Keep functions small and focused; one concern per file/module.
- Write self-documenting code; comments explain why, not what.
- Prefer dependency injection for testability.
- Use feature flags for incomplete features.
- Use config files or environment variables for environment-specific settings.
- Maintain one source of truth for business state. Temporary UI state, cached state, and persisted backend state must not become parallel truths.
- Transitional paths are temporary. Once a new implementation is stable, remove old branches, old interfaces, old mocks, and compatibility layers.
- Extract repeated request flow, response handling, auth/header assembly, validation, and state reconciliation into helpers or shared layers.
- Centralize default values, system prompts, placeholder structures, and fixed constants.
- Public interfaces, persisted fields, and state structures must have a current owner and caller. Delete unused ones.
- After large feature work, run an explicit cleanup pass for dead code, duplicated helpers, stale interfaces, and naming drift.
Code Style
- Python: 4-space indentation, Black style, max line length 100.
- TypeScript: 2-space indentation, Prettier style, max line length 100.
- No trailing whitespace.
- Empty line at end of file.
- Sort imports alphabetically inside groups.
- Never use wildcard imports.
- Avoid unclear abbreviations except common ones such as
id,ok,err. - Prefer descriptive names.
- Keep functions around 50 lines or less where practical.
- Split files before they become mixed-responsibility modules.
Import Order
Python:
# stdlib -> third-party -> local
import json
from datetime import datetime
from fastapi import APIRouter
from sqlalchemy.orm import Session
from app.core.config import settings
TypeScript:
// React -> third-party -> local
import { useEffect, useState } from 'react'
import axios from 'axios'
import { api } from '@/services/api'
Type Rules
- Use type hints throughout Python.
- Define TypeScript interfaces/types for all structured data.
- Avoid
Any; use specific unions, generics, orunknownwhere appropriate. - Prefer typed helpers over repeated type casting.
Verify
- Use deterministic checks before broad manual inspection:
git diff --check
rg -n "TODO|FIXME|console\.log|debugger|print\(" <changed-paths>
Module: security
Load When
Always.
Must
- Never commit
.env, secrets, keys, tokens, or credentials. - Use environment variables or the configured settings store for credentials.
- Validate and sanitize user input.
- Use parameterized database queries.
- Never store plain-text passwords.
- Hash passwords with bcrypt/argon2.
- Use short-lived JWT tokens when auth tokens are involved.
- Use token blacklist or equivalent revocation support for logout.
- Do not expose full tokens in UI. Show only a short prefix and mask the rest.
Verify
git diff --name-only HEAD
rg -n "api[_-]?key|client_secret|BEGIN .*PRIVATE KEY|AKIA[0-9A-Z]" .
Module: workflow
Load When
Always.
Git
- Do not revert user changes unless explicitly requested.
- Do not force push to protected branches.
- Use clear commit messages.
- Run relevant tests and builds before committing.
- Frontend package management must use Bun only.
- Never use
npm,pnpm, oryarnin the frontend project. - Verify package legitimacy before adding dependencies.
- Prefer maintained, widely used libraries.
- Pin dependency versions in
pyproject.toml,uv.lock, andpackage.json.
Deterministic Context
- Prefer compact CLI evidence over reading large files or full diffs:
git status --short
git diff --stat HEAD
git diff --name-only HEAD
git diff --unified=0 HEAD -- <path>
rg -n "<pattern>" <path>
Module: docs
Load When
Writing, translating, linking, restructuring, or publishing docs.
Must
- Chinese docs under
docs/technical/zh/must be Chinese prose, not copied English placeholders. - Keep technical identifiers, API paths, config keys, code symbols, and product names in English where appropriate.
- Explain why a change exists, not only what files changed.
- Prefer updating an existing relevant doc over creating a duplicate.
- Use
##and###headings; avoid going deeper than three levels. - Use fenced code blocks with language tags.
- Use tables when comparing options or listing parameters.
- Do not reference PR numbers, issue numbers, or the current conversation.
- Internal links inside
docs/technical/zh/should point todocs/technical/zh/...unless intentionally linking to English-only docs. - Public Docs UI must only expose documents explicitly registered in
frontend/src/pages/Docs/docs-content.ts. - Development plans and task notes under
docs/plans/are not automatically public documentation.
Required Content
- Background/problem.
- Core design decisions and rationale.
- Key snippets or focused examples.
- Related files and each file's role.
- Operational caveats or verification steps when relevant.
Verify
git diff --stat HEAD
git diff --name-only HEAD
ls docs/technical/zh/
rg -n "\]\(([^)]+)\)" docs/technical/zh/<doc>.md
rg -n "/home/ray/dev/linkong/planet/docs/technical/(?!zh|en)" docs/technical/zh --pcre2
Check zh/en duplicates:
python - <<'PY'
from pathlib import Path
same = []
for en in sorted(Path("docs/technical/en").glob("*.md")):
zh = Path("docs/technical/zh") / en.name
if zh.exists() and en.read_text() == zh.read_text():
same.append(en.name)
if same:
raise SystemExit("identical en/zh docs: " + ", ".join(same))
print("no identical en/zh docs")
PY
Module: uiux
Load When
Changing layout, visual hierarchy, controls, interaction states, responsive behavior, or accessibility.
Must
- Backend/admin pages are single-screen workspaces first, not long landing pages.
- Common desktop viewports should show the page header, summary/controls, and main work area.
- The main work area gets most available height.
- If text, controls, or tables become unreadable, give that region an internal scrollbar instead of crushing it.
- Overflow ownership must be explicit:
- parent height chain is valid
- height-constrained flex parents use
min-height: 0 - only the intended scroll node owns
overflow: auto
- Do not use
overflow: hiddenas a final fix unless another child owns scrolling. - Tabs define their own scroll strategy; hidden panes must stay hidden.
- Long-form content such as AI briefs, logs, Markdown, raw JSON, and help text should stay readable.
- Prefer stable readable minimum heights plus scrolling for constrained content.
- Avoid brittle
100vh/100vwin embedded/admin shells; preferheight: 100%chains. - Verify layouts under browser zoom 125% and 150% when changing height-critical screens.
- Avoid wrapper components with implicit layout behavior, such as
Space, in height-critical scroll regions unless the generated DOM is accounted for. - Any UI state that hides data or a layer must also reconcile hover, lock, tooltip, and selection state.
Visual Controls
- Use icons in buttons for common tools/actions when an established icon exists.
- Keep icon-only buttons accessible with
aria-labelandtitle. - Use segmented controls for modes, switches/checkboxes for binary settings, sliders/inputs for numeric values, menus/selects for option sets, and tabs for views.
- Connection-test actions for endpoint/Base URL inputs must use the shared
ConnectionTestInputpattern: a single plug/connector icon at the input suffix, no adjacent text button; disabled integrations should grey out the field and its test action. - Do not put cards inside cards.
- Do not use visible in-app text to explain obvious UI features or styling.
- Text must fit within its parent on mobile and desktop.
- Do not scale font size with viewport width.
- Letter spacing should usually be
0.
Verify
changed=$(git diff --name-only HEAD -- frontend/src)
[ -z "$changed" ] || rg -n "overflow|min-height|Space|Tabs|aria-label|title=" $changed
Module: frontend
Load When
Editing React, TypeScript, CSS, Vite, Bun, admin console, public Docs UI, or client-side services.
Must
- Use Bun for frontend commands:
bun install
bun run --cwd frontend build
- Never use
npm,pnpm, oryarn. - Keep shared behavior in reusable components/services, not page-local copies.
- Prefer existing project components and patterns.
- Keep page state, backend state, and persisted state clearly separated.
- Presentation state must not pretend to be business state.
- Loading, error, stopped, retry, edit, and view states need explicit semantics.
- Responsive adaptations must preserve the primary action path.
- Markdown rendering behavior belongs in the shared Markdown renderer, not individual docs.
- Public Docs navigation must be whitelist-driven through metadata, not file-system fallback.
TypeScript/CSS
- Define interfaces for API payloads and component props.
- Avoid broad casts.
- Prefer CSS classes over inline styles except for truly dynamic values.
- For fixed-format UI elements, define stable dimensions with
aspect-ratio, grid tracks, min/max constraints, or container-relative sizing.
Verify
bun run --cwd frontend build
git diff --check -- frontend
rg -n "npm|pnpm|yarn" frontend package.json
Module: backend
Load When
Editing FastAPI, SQLAlchemy, collectors, database models, migrations, services, API routes, or performance-sensitive code.
Must
- Use custom exceptions for domain errors.
- Never swallow errors silently.
- Distinguish recoverable and unrecoverable errors.
- Log errors with useful context and appropriate level.
- Propagate errors unless explicitly handled.
- Repeated
load -> validate -> transform -> respondflow should be centralized. - Each data source has its own collector class.
- Collectors must inherit the repository's base collector abstraction when available.
- Collectors implement
fetch()andtransform()or the current project-equivalent pipeline hooks. - Support incremental and full sync modes where the source allows it.
Query Performance
- Never load whole tables into Python for filtering, pagination, counting, dedupe, or summary aggregation.
- Push filters, sorting, pagination,
count,distinct, and grouped statistics down to the database. - Summary/dashboard endpoints should prefer aggregate queries or aggregate endpoints.
- Avoid selecting large JSON/text payload columns on hot paths unless needed.
- List endpoints default to database-side pagination.
- When a query is slow, first check:
- full-table ORM loads
- Python-side post-filtering
- repeated summary queries that can be merged
- repeated per-request recomputation that should be cached or aggregated
Country Data
- Data sources carrying country, region, or territory fields must validate against
backend/app/core/countries.py. - Use
normalize_country(value)as the single gate. - If normalization returns
None, log and reject or flag the value. - Do not override canonical political labels with raw source labels.
- Add aliases to
COUNTRY_ENTRIES; do not scatter aliases across collectors or API handlers. - Frontend country labels should come from the canonical dictionary after normalization.
Verify
git diff --name-only HEAD -- backend
python3 -m py_compile <changed-python-files>
rg -n "scalars\\(\\)\\.all\\(\\)|\\.all\\(\\).*\\[:|len\\(.*\\.all\\(" backend/app
rg -n "text\\(\"SELECT \\*|execute.*SELECT \\*" backend/app
rg -n "normalize_country|COUNTRY_ENTRIES" backend/app
Module: earth
Load When
Editing frontend/public/earth, 3D Earth, canvas/Three.js rendering, BGP/vessel/satellite/cable layers, geographic boundaries, or Earth marker icons.
Must
- Keep rendering state and UI state explicitly synchronized.
- If a layer is hidden, clear or reconcile related hover, lock, tooltip, and selection state.
- Avoid one-off visual patches before checking render order, coordinate ownership, and data lifecycle.
- Use Three.js for 3D elements.
- Verify 3D/canvas work with real rendering, not only TypeScript build.
- Do not let loading messages, phase labels, or optimistic UI override real backend task state.
- WebSocket data frames should include timestamps, type, and payload when streaming Earth state.
- Default heartbeat for real-time streams is 30 seconds unless a protocol states otherwise.
Icon System
Canvas-drawn marker icons for Earth must have canonical SVG sources in:
frontend/public/earth/assets/icons/
This directory is the single source of truth for icon geometry. Canvas or Three.js drawing code may use Path2D strings or draw calls derived from these SVGs, but the shape must originate here.
Naming:
| Prefix | Context |
|---|---|
marker- |
Surface map markers |
bgp- |
BGP/routing layer icons and event symbols |
compute- |
Compute center markers |
Rules:
- Use
fill="currentColor"for single-color icons. - Hardcode brand colors only when color is part of icon identity.
- State variants are handled by calling code via color/opacity; do not create separate SVGs per state.
- Use the native canvas coordinate space as
viewBox, typically0 0 128 128. - When adding an icon, create the SVG, document it in this module, and reference its geometry from rendering code.
Current icons:
| File | Used in | Description |
|---|---|---|
marker-landing-point.svg |
cables.js |
Cable landing point pin |
bgp-collector.svg |
bgp.js |
BGP collector marker |
bgp-glow-dot.svg |
bgp.js |
Base radial glow dot |
bgp-event-ring.svg |
bgp.js |
Event ring overlay |
bgp-event-triangle.svg |
bgp.js |
Origin anomaly |
bgp-event-exclamation.svg |
bgp.js |
Withdraw event |
bgp-event-wave.svg |
bgp.js |
Flap event |
bgp-event-burst.svg |
bgp.js |
Specific/burst anomaly |
bgp-event-leak.svg |
bgp.js |
Route leak |
bgp-event-dot.svg |
bgp.js |
Generic event |
compute-supercomputer.svg |
compute-centers.js |
Supercomputer |
compute-gpu-cluster.svg |
compute-centers.js |
GPU cluster |
Verify
bun run --cwd frontend build
rg -n "hover|locked|selected|tooltip|visible|Path2D|drawImage" frontend/public/earth
ls frontend/public/earth/assets/icons/
Module: ai
Load When
Editing AI Provider, LLM gateway, AI Playground, prompt templates, model selection, custom collector mapping generation, or LLM-assisted data transformation.
Must
- AI provider endpoint/base URL/model/token configuration belongs in settings/integration config, not hardcoded page state.
- The local API route used by the console is not the same as the external LLM provider base URL.
- Common LLM provider presets should be selectable and refreshable from provider docs or catalog logic.
- Store fallback/default provider config centrally.
- Credential previews must reuse the existing product masking convention instead of inventing page-local display logic.
- Never send secrets to logs or docs.
- LLMs may assist with mapping generation or unknown API exploration, but runtime collection should use saved deterministic mapping rules.
- If custom collectors transform into existing domain data, require an explicit target schema.
- If custom collectors introduce entirely new data, do not pretend Earth can use it until a corresponding feature exists.
- Prompts, mapping schemas, default examples, and provider constants must be centralized.
Verify
rg -n "AI_PROVIDER|provider_api|base_url|api_key|service_token|prompt|mapping" backend aiprovider frontend/src
git diff --check -- backend aiprovider frontend/src
Module: release
Load When
The user asks to 发版, bump version, release, commit/push release work, or update changelog/version history as part of a release.
Must
- Treat release work as release workflow, not a plain commit.
- Use
.codex/skills/release/SKILL.mdwhen Codex performs a release. - Version bump rules:
feature->+0.1.0improvement->+0.0.1bugfix->+0.0.1docs,maintenance,refactordo not bump unless explicitly requested
- Mixed bugfix and small feature/UI work defaults to
improvementunless the user explicitly chooses another release type. - A release bump updates all version-bearing files together:
VERSIONfrontend/package.jsonpyproject.tomluv.lock
- A release bump updates release records together:
docs/CHANGELOG.mddocs/version-history.md
uv.lockmust be regenerated byuv lock, never edited manually.- Before committing a release, verify target version consistency.
- Before pushing a release, run the smallest relevant validation for the changed scope and report what was or was not validated.
- Do not include generated runtime output directories in release commits.
Verify
git branch --show-current
git status --short
cat VERSION
rg -n "\"version\":|^version =|version = " frontend/package.json pyproject.toml uv.lock
git diff --stat HEAD