ещё обновление доки
This commit is contained in:
@@ -14,11 +14,12 @@
|
||||
2. Прочитать файл текущей цели, указанный там как `Current target`.
|
||||
3. Прочитать [`targets/DEVELOPMENT_ROADMAP.md`](targets/DEVELOPMENT_ROADMAP.md) и соответствующий subsystem plan из `targets/roadmap/`.
|
||||
4. Прочитать [`docs/README.md`](docs/README.md) и связанные с задачей нормативные документы.
|
||||
5. Прочитать обязательный [`docs/DOCUMENTATION_STANDARD.md`](docs/DOCUMENTATION_STANDARD.md) и определить, какие API docs, module spec и diagrams затрагивает задача.
|
||||
6. Для renderer-задач прочитать [`RENDER.md`](RENDER.md).
|
||||
7. Проверить рабочее дерево и не перезаписывать чужие изменения.
|
||||
8. Перед созданием сложной подсистемы или добавлением dependency проверить [`docs/TOOLING_CATALOG.md`](docs/TOOLING_CATALOG.md), зарегистрировать найденные готовые решения и провести bounded evaluation вместо немедленного вендоринга.
|
||||
9. При командной работе прочитать [`docs/TEAM_WORKFLOW.md`](docs/TEAM_WORKFLOW.md), проверить активные claims/draft PRs и объявить стабильный Agent ID до изменений.
|
||||
5. Прочитать обязательный [`docs/CODING_STANDARD.md`](docs/CODING_STANDARD.md): явные имена и KISS имеют приоритет.
|
||||
6. Прочитать обязательный [`docs/DOCUMENTATION_STANDARD.md`](docs/DOCUMENTATION_STANDARD.md) и определить, какие API docs, module spec и diagrams затрагивает задача.
|
||||
7. Для renderer-задач прочитать [`RENDER.md`](RENDER.md).
|
||||
8. Проверить рабочее дерево и не перезаписывать чужие изменения.
|
||||
9. Перед созданием сложной подсистемы или добавлением dependency проверить [`docs/TOOLING_CATALOG.md`](docs/TOOLING_CATALOG.md), зарегистрировать найденные готовые решения и провести bounded evaluation вместо немедленного вендоринга.
|
||||
10. При командной работе прочитать [`docs/TEAM_WORKFLOW.md`](docs/TEAM_WORKFLOW.md), проверить активные claims/draft PRs и объявить стабильный Agent ID до изменений.
|
||||
|
||||
Если задача пользователя противоречит target-порядку, прямое указание пользователя имеет приоритет, но агент обязан сохранить архитектурные границы и отметить влияние на roadmap.
|
||||
|
||||
@@ -39,6 +40,9 @@
|
||||
- Каждый новый/существенно изменённый модуль обязан иметь актуальную specification в `docs/modules/`, inline documentation публичного API и data-flow diagram по `docs/DOCUMENTATION_STANDARD.md`.
|
||||
- Stateful/async/cross-layer работа обязана документировать state/sequence diagram, ownership, threading, failure и recovery paths.
|
||||
- Документация обновляется в том же work package, что код. Handoff без обязательной документации имеет статус только `PARTIAL`.
|
||||
- Не сокращать имена ради краткости. Variable/function/type должен явно описывать назначение, domain context, units и coordinate space, когда они неоднозначны.
|
||||
- Следовать KISS: использовать самое простое корректное решение, не вводить premature abstractions/frameworks/optimizations и изолировать неизбежную сложность.
|
||||
- Имена `manager`, `helper`, `utils`, `data`, `info`, `process`, `handle` без точного контекста считаются design smell и требуют переименования или обоснования.
|
||||
|
||||
## Метки состояния
|
||||
|
||||
@@ -63,6 +67,7 @@
|
||||
4. Не осталось обязательных незакрытых пунктов или скрытых заглушек.
|
||||
5. Обновлены `targets/README.md` и матрица функций, если применимо.
|
||||
6. Публичный API, module spec, input/output tables и обязательные diagrams соответствуют фактической реализации.
|
||||
7. Код соответствует `docs/CODING_STANDARD.md`: понятные имена, простой data flow и обоснованная сложность.
|
||||
|
||||
Агент НЕ ДОЛЖЕН ставить `DONE` только потому, что код компилируется. Если пользователь явно принял частичный результат, статус остаётся `ACTIVE`, а принятое ограничение записывается в Evidence.
|
||||
|
||||
|
||||
@@ -51,6 +51,14 @@
|
||||
- Sequence/state/dependency diagrams:
|
||||
- Source map/status updates:
|
||||
|
||||
## Simplicity and naming
|
||||
|
||||
- Important names introduced:
|
||||
- Simplest considered solution:
|
||||
- Rejected complexity/abstractions:
|
||||
- Unavoidable complexity and justification:
|
||||
- Measured optimization evidence:
|
||||
|
||||
## Status
|
||||
|
||||
- State: claimed
|
||||
|
||||
@@ -0,0 +1,252 @@
|
||||
# OpenWC Coding Standard
|
||||
|
||||
## Главные принципы
|
||||
|
||||
1. Код читается значительно чаще, чем пишется.
|
||||
2. Явное и точное имя предпочтительнее короткого и двусмысленного.
|
||||
3. KISS применяется по умолчанию: выбирается самое простое решение, которое корректно выполняет текущую задачу и сохраняет архитектурные границы.
|
||||
4. Сложность допускается только там, где она следует из предметной области, формата, протокола, производительности или совместимости 3.3.5a.
|
||||
5. Неизбежная сложность должна быть локализована, протестирована и документирована.
|
||||
|
||||
## Имена
|
||||
|
||||
Не нужно бояться длинных имён переменных, функций, типов, сигналов и файлов. Имя должно позволять понять назначение сущности без поиска всех мест использования.
|
||||
|
||||
Хорошо:
|
||||
|
||||
```gdscript
|
||||
var terrain_control_splat_cache_finalize_queue: Array = []
|
||||
var maximum_concurrent_terrain_upgrade_tasks: int = 1
|
||||
|
||||
func enqueue_terrain_control_splat_cache_finalize(tile_coordinate: Vector2i) -> void:
|
||||
pass
|
||||
|
||||
func should_retain_streaming_tile_outside_visible_radius(tile_state: TileState) -> bool:
|
||||
return false
|
||||
```
|
||||
|
||||
Плохо:
|
||||
|
||||
```gdscript
|
||||
var q = []
|
||||
var max_t = 1
|
||||
|
||||
func do_ctl(p):
|
||||
pass
|
||||
|
||||
func chk(s):
|
||||
return false
|
||||
```
|
||||
|
||||
Длина не является самоцелью. Не повторять контекст, который уже однозначно задаётся типом или модулем:
|
||||
|
||||
```gdscript
|
||||
# Внутри TerrainStreamingService:
|
||||
func enqueue_finalize(tile: TerrainTile) -> void:
|
||||
pass
|
||||
```
|
||||
|
||||
Такое имя допустимо, если `finalize` в этом классе имеет только одно значение. Если существуют terrain mesh, material и liquid finalization, имя должно уточнять конкретную операцию.
|
||||
|
||||
## Naming rules
|
||||
|
||||
- Типы/classes: `PascalCase`.
|
||||
- GDScript functions/variables/signals: `snake_case`.
|
||||
- Constants: `UPPER_SNAKE_CASE`.
|
||||
- Private implementation members: `_leading_underscore` по Godot convention.
|
||||
- C++ следует Godot/GDExtension convention внутри существующего native module; новый API не смешивает стили в одной области.
|
||||
- Boolean: `is_`, `has_`, `can_`, `should_`, `needs_`, `was_`.
|
||||
- Collections называются во множественном числе или по роли: `loaded_tiles`, `pending_packet_events`, `entity_by_guid`.
|
||||
- Functions начинаются с действия: `load_`, `parse_`, `build_`, `enqueue_`, `apply_`, `validate_`, `resolve_`, `convert_`, `release_`.
|
||||
- Units указываются в имени: `_milliseconds`, `_seconds`, `_bytes`, `_meters`, `_tiles`, `_radians`, `_degrees`.
|
||||
- Coordinate space указывается, если возможна путаница: `canonical_wow_position`, `godot_world_position`, `adt_tile_coordinate`.
|
||||
- Версия/build/profile указывается в типе или namespace, если semantics различаются: `Wotlk335ProtocolProfile`.
|
||||
|
||||
Допустимые устоявшиеся доменные сокращения:
|
||||
|
||||
- WoW, MPQ, BLP, DBC;
|
||||
- ADT, WDT, WDL;
|
||||
- M2, WMO;
|
||||
- GUID, SRP, API, UI;
|
||||
- LOD, RID, GPU, CPU;
|
||||
- SQL, TCP.
|
||||
|
||||
Новые локальные сокращения из двух-трёх букв без общеизвестного значения запрещены.
|
||||
|
||||
## Запрещённые размытые имена
|
||||
|
||||
Избегать без уточнения:
|
||||
|
||||
```text
|
||||
data
|
||||
info
|
||||
item
|
||||
object
|
||||
value
|
||||
temp
|
||||
result
|
||||
state
|
||||
manager
|
||||
helper
|
||||
utils
|
||||
process
|
||||
handle
|
||||
do_work
|
||||
```
|
||||
|
||||
Они допустимы только когда тип и ближайший scope делают значение полностью однозначным. Например, `parse_packet() -> PacketParseResult` может использовать локальную переменную `result`, если функция мала и другого результата нет.
|
||||
|
||||
`Manager`, `Helper`, `Utils` почти всегда скрывают несколько обязанностей. Предпочтительны названия по роли:
|
||||
|
||||
```text
|
||||
WorldSession
|
||||
StreamingTargetPlanner
|
||||
RenderBudgetScheduler
|
||||
CoordinateMapper
|
||||
AssetRepository
|
||||
QuestValidator
|
||||
ServerSchemaAdapter
|
||||
```
|
||||
|
||||
## KISS decision order
|
||||
|
||||
При выборе реализации двигаться по порядку:
|
||||
|
||||
1. Простая typed function с явными inputs/outputs.
|
||||
2. Маленький value object или immutable result.
|
||||
3. Небольшой service с одной ответственностью.
|
||||
4. Composition нескольких services.
|
||||
5. Interface/strategy только при реальной вариативности или boundary.
|
||||
6. Generic framework только после нескольких подтверждённых use cases.
|
||||
7. Native/low-level optimization только после измеренного bottleneck.
|
||||
|
||||
Не переходить на следующий уровень, если предыдущий решает задачу без нарушения correctness и architecture.
|
||||
|
||||
## Простота функций
|
||||
|
||||
- Одна функция выполняет одну логическую операцию.
|
||||
- Название функции описывает observable effect.
|
||||
- Inputs и outputs явные; hidden global state минимален.
|
||||
- Guard clauses предпочтительнее глубокой вложенности.
|
||||
- Happy path должен читаться сверху вниз.
|
||||
- Side effects не смешиваются с pure calculation без необходимости.
|
||||
- Parsing, validation, state mutation и presentation отделяются.
|
||||
- Функция не принимает набор boolean flags, меняющих её смысл.
|
||||
|
||||
Плохо:
|
||||
|
||||
```gdscript
|
||||
func load_tile(path: String, high: bool, async: bool, editor: bool):
|
||||
pass
|
||||
```
|
||||
|
||||
Лучше:
|
||||
|
||||
```gdscript
|
||||
func request_streaming_tile_load(request: StreamingTileLoadRequest) -> void:
|
||||
pass
|
||||
```
|
||||
|
||||
При этом `StreamingTileLoadRequest` оправдан только если параметры действительно образуют устойчивый contract. Для двух простых аргументов не нужно создавать объект только ради архитектурности.
|
||||
|
||||
## Простота data flow
|
||||
|
||||
- Один владелец mutable state.
|
||||
- Один канонический тип для одной концепции.
|
||||
- Один mapper для coordinate conversion.
|
||||
- Один authoritative source для content/runtime state.
|
||||
- Изменения передаются commands/events/read models, а не чтением чужих внутренних dictionaries.
|
||||
- Не создавать второй cache, registry или event bus без описанной отдельной ответственности.
|
||||
- Не использовать строки и `call()` как основной type system.
|
||||
- Dictionary допустим на binary/dynamic boundary; внутри domain данные переводятся в typed representation.
|
||||
|
||||
## Простота архитектуры
|
||||
|
||||
- Не вводить interface только потому, что «когда-нибудь может появиться второй backend».
|
||||
- Interface обязателен на реальной внешней границе: renderer facade, protocol profile, Lua VM, server schema adapter, asset repository.
|
||||
- Не создавать base class с одним наследником без конкретного boundary/invariant.
|
||||
- Предпочитать composition inheritance.
|
||||
- Не строить универсальную ECS, service container, message broker или plugin framework до подтверждённых требований OpenWC.
|
||||
- Не переносить архитектуру reference-проекта целиком; извлекать только проверенное решение конкретной проблемы.
|
||||
|
||||
## Работа со сложностью
|
||||
|
||||
Сложность считается оправданной для:
|
||||
|
||||
- binary formats и build-specific layouts;
|
||||
- encrypted/framed network protocol;
|
||||
- incremental world streaming;
|
||||
- animation/material compatibility;
|
||||
- Lua/FrameXML/taint semantics;
|
||||
- cross-core schema mappings;
|
||||
- async jobs, cancellation и deterministic cleanup;
|
||||
- performance-critical batching после profiling.
|
||||
|
||||
Если сложность неизбежна:
|
||||
|
||||
1. Изолировать её в одном модуле.
|
||||
2. Дать точные имена промежуточным этапам.
|
||||
3. Разбить pipeline на небольшие transformations.
|
||||
4. Добавить data-flow/sequence/state diagram.
|
||||
5. Зафиксировать invariants и ownership.
|
||||
6. Создать fixtures для edge cases.
|
||||
7. Объяснить, почему более простое решение недостаточно.
|
||||
|
||||
## Conditions and branching
|
||||
|
||||
- Предпочитать именованные predicates длинным boolean expressions.
|
||||
- Branch по capability/profile должен быть локальным и типизированным.
|
||||
- Не распространять `if core == "azerothcore"` по проекту; использовать adapter/capability.
|
||||
- Не смешивать Blizzlike и Enhanced branches в каждом shader/service: выбирать profile/strategy на boundary.
|
||||
- Pattern/table-driven mapping предпочтительнее сотен одинаковых `if`, если таблица остаётся читаемой и валидируемой.
|
||||
|
||||
## Comments
|
||||
|
||||
Комментарий объясняет `why`, invariant, source behavior или ограничение. Код и имя объясняют `what`.
|
||||
|
||||
Хорошо:
|
||||
|
||||
```gdscript
|
||||
# WoW M2 bone indices are relative to the skin-section bone palette,
|
||||
# not directly to the model-wide bone array.
|
||||
```
|
||||
|
||||
Плохо:
|
||||
|
||||
```gdscript
|
||||
# Increment index by one.
|
||||
index += 1
|
||||
```
|
||||
|
||||
TODO/FIXME обязан содержать target/work-package ID или diagnostic code.
|
||||
|
||||
## Error handling
|
||||
|
||||
- Ошибка содержит operation, subject и actionable context.
|
||||
- Не возвращать пустой Dictionary как неразличимое сочетание `not found`, `invalid` и `unsupported`.
|
||||
- Expected failure моделируется typed result/status; programming invariant может использовать assert в подходящем profile.
|
||||
- Не проглатывать ошибку ради продолжения renderer/editor: degraded behavior должен быть виден diagnostics.
|
||||
- Recovery path проще и предпочтительнее сложной попытки угадать состояние.
|
||||
|
||||
## Performance and KISS
|
||||
|
||||
- Не оптимизировать по предположению.
|
||||
- Сначала baseline/profile, затем smallest measured fix.
|
||||
- Batch/buffer/RenderingServer/native path вводится после доказательства bottleneck.
|
||||
- Оптимизированный path обязан иметь простой contract и reference tests.
|
||||
- Медленный понятный reference implementation полезен как oracle для optimized implementation.
|
||||
- Сложная оптимизация удаляется или упрощается, если она не даёт измеримого результата.
|
||||
|
||||
## Review checklist
|
||||
|
||||
- Можно ли понять назначение сущности по имени?
|
||||
- Есть ли двусмысленные сокращения?
|
||||
- Выполняет ли функция одну операцию?
|
||||
- Можно ли убрать abstraction без потери correctness/boundary?
|
||||
- Есть ли скрытый mutable state или side effect?
|
||||
- Не появился ли второй источник истины?
|
||||
- Измерена ли сложная optimization?
|
||||
- Изолирована и документирована ли неизбежная сложность?
|
||||
- Соответствуют ли API docs и diagrams фактическому коду?
|
||||
|
||||
Если reviewer не может объяснить data flow модуля после чтения имён, public API и module spec, work package не готов к интеграции.
|
||||
@@ -16,6 +16,8 @@
|
||||
- как проверить fidelity, correctness и performance;
|
||||
- какие части реализованы, запланированы или известны как gap.
|
||||
|
||||
Правила именования, KISS и локализации неизбежной сложности определены в [`CODING_STANDARD.md`](CODING_STANDARD.md). Документация и ясные имена дополняют друг друга: комментарий не должен компенсировать неудачное имя.
|
||||
|
||||
## Уровни документации
|
||||
|
||||
### 1. Inline API documentation
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
| [TEAM_WORKFLOW.md](TEAM_WORKFLOW.md) | Ветки/worktree, task claims, ownership, handoff, integration и conflict protocol |
|
||||
| [DOCUMENTATION_STANDARD.md](DOCUMENTATION_STANDARD.md) | Обязательные API docs, module specs, data-flow/state/sequence diagrams и documentation gate |
|
||||
| [modules/README.md](modules/README.md) | Реестр фактических модулей и шаблон их спецификаций |
|
||||
| [CODING_STANDARD.md](CODING_STANDARD.md) | Явные длинные имена, KISS, простота функций/data flow и правила оправданной сложности |
|
||||
|
||||
## Обязательный workflow изменения функции
|
||||
|
||||
|
||||
@@ -268,9 +268,10 @@ Handoff обязан содержать:
|
||||
4. Запускает package verification и затронутые общие gates.
|
||||
5. Проверяет docs, migrations, cache versions и fidelity statement.
|
||||
6. Проверяет documentation gate из `docs/DOCUMENTATION_STANDARD.md`: API docs, inputs/outputs, diagrams, ownership и recovery.
|
||||
7. Merge/squash выполняет в соответствии с историей work package.
|
||||
8. После merge запускает post-merge smoke.
|
||||
9. Закрывает claim marker-ом:
|
||||
7. Проверяет coding gate из `docs/CODING_STANDARD.md`: ясные имена, KISS, отсутствие premature abstractions и скрытого data flow.
|
||||
8. Merge/squash выполняет в соответствии с историей work package.
|
||||
9. После merge запускает post-merge smoke.
|
||||
10. Закрывает claim marker-ом:
|
||||
|
||||
```text
|
||||
<!-- OPENWC_INTEGRATION:ACCEPTED:M01-FND-COORDS-001:<merge-commit> -->
|
||||
|
||||
@@ -68,6 +68,7 @@ Wowser зарегистрирован как независимый MIT referenc
|
||||
- отсутствие новых нарушений dependency rules;
|
||||
- обновлённые документы и diagnostics;
|
||||
- выполнен documentation gate: inline public API, module spec, inputs/outputs и обязательные diagrams;
|
||||
- выполнен coding gate: явные имена, KISS, отсутствие premature abstraction и необоснованной optimization;
|
||||
- проходят `tools/verify_coordination.ps1` и `tools/verify_documentation.ps1`;
|
||||
- воспроизводимость без proprietary данных в Git.
|
||||
|
||||
|
||||
@@ -97,6 +97,14 @@ Nightly/weekly:
|
||||
- Tooling candidates tracked in `docs/TOOLING_CATALOG.md` with status and pinned version.
|
||||
- Feature coverage links implementation, tests, fidelity evidence and known gaps.
|
||||
- Generated API docs for documented GDScript/GDExtension public surface включаются в quality gate, когда pipeline подготовлен.
|
||||
|
||||
## QAR-9A. Code clarity and KISS
|
||||
|
||||
- Naming и simplicity проверяются по `docs/CODING_STANDARD.md`.
|
||||
- Длинное точное имя предпочтительнее неочевидного сокращения; length не является целью сама по себе.
|
||||
- Complexity metrics используются как сигнал для review, а не автоматическая причина переписывания domain-heavy code.
|
||||
- Premature generic frameworks, service locators, duplicate registries и unmeasured native optimizations блокируют integration.
|
||||
- Неизбежно сложный parser/protocol/streaming/UI security code обязан быть изолирован, иметь reference fixtures и диаграмму.
|
||||
- Contributor workflow describes smallest reproducible diagnostic commands.
|
||||
|
||||
## QAR-10. Packaging and release
|
||||
|
||||
@@ -8,6 +8,7 @@ $failures = [System.Collections.Generic.List[string]]::new()
|
||||
$requiredFiles = @(
|
||||
'AGENTS.md',
|
||||
'docs\README.md',
|
||||
'docs\CODING_STANDARD.md',
|
||||
'docs\DOCUMENTATION_STANDARD.md',
|
||||
'docs\modules\README.md',
|
||||
'docs\modules\TEMPLATE.md',
|
||||
@@ -26,6 +27,9 @@ if (Test-Path -LiteralPath $agentGuide) {
|
||||
if ($agentContent -notmatch 'DOCUMENTATION_STANDARD\.md') {
|
||||
$failures.Add('AGENTS.md does not reference docs/DOCUMENTATION_STANDARD.md')
|
||||
}
|
||||
if ($agentContent -notmatch 'CODING_STANDARD\.md') {
|
||||
$failures.Add('AGENTS.md does not reference docs/CODING_STANDARD.md')
|
||||
}
|
||||
}
|
||||
|
||||
$requiredHeadings = @(
|
||||
|
||||
Reference in New Issue
Block a user