Repository Guidelines
Project Structure & Module Organization
- Go monorepo: binaries in
cmd/, core implementation ininternal/, stable exported helpers inpkg/. - Frontend UI:
web/. - Configs & assets:
configs/,descriptors/,scripts/,docs/, runtime data indata/. - Protocol/IDL:
proto/, generated stubs inpkg/pb. - SDKs:
sdks/<lang>for code,docs/sdks/<lang>for formal docs.
Build, Test, and Development Commands
- Build all server-side binaries:
make build - Build a specific binary:
make server,make agent,make worker,make ingest - Generate protobuf code:
make proto - Run tests:
make test - Build docs:
cd docs && pnpm install && pnpm run build - Build dashboard:
cd web && pnpm install && pnpm build
Coding Style & Naming Conventions
- Go:
gofmt/goimports; packages lowercase; exported idsCamelCase; usecontext.Contextfirst; structured logs. - New entrypoints go under
cmd/; do not reintroduceservices/*layout or stale document references. - TypeScript/React: Prettier + ESLint; 2-space indent; components
PascalCase; hooksuseX. - Commits: Conventional Commits (
feat(scope): ...,fix,chore,docs).
Testing Guidelines
- Go unit tests co-locate as
*_test.go; prefer table-driven tests. - Frontend:
cd web && pnpm testorpnpm test:coverage. - Add tests when touching RBAC, APIs, routing, analytics processing, or descriptor resolution.
Commit & Pull Request Guidelines
- PR should include: what changed, why, and how it was verified.
- When adding APIs or permissions, update the matching files under
configs/. - Keep diffs focused; ensure
make testpasses before merge.
Security & Configuration Tips
- Secrets go through environment variables, not hardcoded YAML.
- Example local run:
./bin/croupier-server --config configs/server.yaml.
Release Tagging
- Server / Agent release tags use
v*, for examplev0.2.0. - SDK release tags use namespaced prefixes:
sdk-js-v*sdk-python-v*sdk-go-v*sdk-java-v*sdk-cpp-v*
- Do not use plain
v*tags for SDK-only releases, otherwise you will target the server/agent release lane.
兼容性与遗留治理(无兼容遗留原则)
本阶段不以向后兼容为约束。新协议、新 SDK、新文档不默认保留旧入口。
硬性规则
- 新代码使用 canonical 命名:协议字段、SDK API、文档术语统一使用当前基线命名(例如
Task而非Job、ProviderConnect而非RegisterLocal、TCP session 而非rpc_addr回拨)。 - 默认删除,不默认保留:重命名或迁移时直接删除旧入口,不留
@Deprecated别名。旧的生成代码、旧文档、旧示例一并清理或归档。 - 暂留必须有门控:若确实需要暂留兼容字段(例如 DB 列删除需 migration、proto 字段删除需 SDK 重生成),必须同时满足:
- 在代码处标注删除条件(什么事件触发后可删)和负责人/期限。
- 在
todo.md登记为独立待办,附受影响路径。 - 提供检测脚本(如
scripts/check-sdk-matrix.sh)能在彻底删除前持续可见。
- 历史归档只进
docs/archive/:迁移说明、旧设计文档移入docs/archive/,不留在主路径文档里作为"当前链路"描述。
检查工具
scripts/check-sdk-matrix.sh:SDK 缺能力、旧 wire name、旧 README 术语均视为失败(exit 1),CI 阻断。allowlist 仅限协议别名模块,且这些模块本身也须为 canonical 命名。rg "StartJob|RegisterLocal|HeartbeatLocal|rpc_addr|LocalControl"只允许出现在docs/archive/、todo.md的门控说明、或生成代码重生成脚本中。
违反示例
- ❌ 新增
startJob作为startTask的别名"方便迁移"。 - ❌ 在 README 中把
rpc_addr/ gRPC 回拨描述为当前链路。 - ❌ 删除旧字段时不写删除条件、不登记 todo。
- ✅ 直接把
startJob改名为startTask,更新所有调用点和测试。
传输层决策(不使用 gRPC)
- 内部 RPC(Server ↔ Agent ↔ SDK)不使用 gRPC,用自研 TCP transport + protobuf。这是从 gRPC 的坑里重构出来的结论,不可逆。
- 理由:gRPC debug 版约 1.7GB、依赖链一周未搞定、游戏后端不需要这么重。详见 传输层决策 — 不使用 gRPC。
- 硬约束:不得新增 gRPC 直接用法;
go.mod残留的google.golang.org/grpc仅为间接依赖,需定期评估移除。 - 新增 RPC 需求走自研 TCP+proto;如需统一 error 协议等能力,在自研 RPC 层补齐(proto
Status/RpcError),不引入 gRPC。
