docs(architecture): привести TOOLS/ARCHITECTURE.md в соответствие с кодом
- Core Principles 2-3: 'универсально/генерируется' отнесено к core/ и resources_gen/, а не ко всему сервис-коду. - API Resilience: 401 НЕ ретраится (isRetryable = 429/502/503/504, только GET) — помечено как незакрытый разрыв со спекой. - Exception Registry: убран удалённый реестр serviceSpecificModifiers (yaml-generator/main.go), описаны ручные модификаторы + несуществующий modifiers.yaml. - Новый раздел 'Lifecycle Vocabulary': три несогласованных словаря destroy. - Rules: 'two registries' -> один реестр + ручные ресурсы.
This commit is contained in:
+42
-11
@@ -9,8 +9,10 @@ reflected here FIRST, then implemented in `gen_v2` and other tools.
|
|||||||
## Core Principles
|
## Core Principles
|
||||||
|
|
||||||
1) YAML per service is generated ONLY from API data.
|
1) YAML per service is generated ONLY from API data.
|
||||||
2) The provider core is universal and must not contain service-specific logic.
|
2) The provider core (`provider/internal/core`) is universal and must not contain
|
||||||
3) Service-specific Go code is fully generated from YAML. No manual edits.
|
service-specific logic.
|
||||||
|
3) Service-specific Go code (`provider/internal/resources_gen`) is fully generated
|
||||||
|
from YAML. No manual edits to generated code.
|
||||||
4) Documentation is generated from the same YAML.
|
4) Documentation is generated from the same YAML.
|
||||||
5) Build artifacts for 3 OS targets are published to the registry, and docs are
|
5) Build artifacts for 3 OS targets are published to the registry, and docs are
|
||||||
published to the website.
|
published to the website.
|
||||||
@@ -107,15 +109,23 @@ Each operation has a kind:
|
|||||||
|
|
||||||
## Provider Model
|
## Provider Model
|
||||||
|
|
||||||
- Core is universal: no service-specific logic inside the core.
|
- Core (`provider/internal/core`) is universal: no service-specific logic inside it.
|
||||||
- Generated service resources contain only schema/params and references.
|
- Generated service resources (`provider/internal/resources_gen`) contain only
|
||||||
|
schema/params and references.
|
||||||
|
- Hand-written service resources live in `provider/internal/resources_core` and are
|
||||||
|
registered in `provider/internal/provider/provider.go` `Resources()`. They are
|
||||||
|
NOT generated; they must not contain arbitrary service logic, only:
|
||||||
|
- a schema, and
|
||||||
|
- wiring between schema fields and the universal core API
|
||||||
|
(`RunInstanceOperationUniversalByCode`, `ResolveRefSvcParamValue`, etc.).
|
||||||
|
|
||||||
### API Resilience
|
### API Resilience
|
||||||
|
|
||||||
- Core MUST retry transient 401 errors from Gateway (3 attempts, exponential backoff).
|
- Core MUST retry transient 401 errors from Gateway (3 attempts, exponential backoff).
|
||||||
Gateway may temporarily reject valid JWT tokens.
|
Gateway may temporarily reject valid JWT tokens.
|
||||||
- GET operations (GetInstanceState, GetInstanceStateRaw) retry 401 with 2s/4s/8s backoff.
|
- **CURRENTLY NOT IMPLEMENTED** — `isRetryable` (`core/http.go`) retries only
|
||||||
- `doRequest` treats 401 as retryable for GET requests (alongside 429, 502, 503, 504).
|
{429, 502, 503, 504}, NOT 401, and only for GET. This is a known gap versus the
|
||||||
|
intent above; fix in `core/http.go` `isRetryable`.
|
||||||
|
|
||||||
### Generated Code Resilience
|
### Generated Code Resilience
|
||||||
|
|
||||||
@@ -208,28 +218,49 @@ From the unified YAML, generate:
|
|||||||
5) Upload provider artifacts to registry.
|
5) Upload provider artifacts to registry.
|
||||||
6) Build and publish docs to site.
|
6) Build and publish docs to site.
|
||||||
|
|
||||||
|
## Lifecycle Vocabulary (single contract)
|
||||||
|
|
||||||
|
⚠️ The destroy-behaviour vocabulary is currently INCONSISTENT across resource kinds:
|
||||||
|
|
||||||
|
1. generated instance resources: runtime flags `suspend_on_destroy` / `keep_on_destroy`;
|
||||||
|
2. generated modifiers: compile-time `delete_strategy` (no runtime flag);
|
||||||
|
3. hand-written modifiers: runtime `keep_on_destroy` only.
|
||||||
|
|
||||||
|
All three express the same intent ("what happens to the platform effect on destroy").
|
||||||
|
Canonical direction: one unified vocabulary/contract for all resource kinds.
|
||||||
|
|
||||||
## Non-Negotiable Rules
|
## Non-Negotiable Rules
|
||||||
|
|
||||||
- No manual edits to generated YAML or generated Go code.
|
- No manual edits to generated YAML or generated Go code.
|
||||||
- Any change must come from API or generator logic updates.
|
- Any change to generated code must come from API or generator logic updates.
|
||||||
- The generator must enforce these rules and fail fast on drift.
|
- The generator must enforce these rules and fail fast on drift.
|
||||||
|
|
||||||
## Exception Registry (service-specific DATA, never logic)
|
## Exception Registry (service-specific DATA, never logic)
|
||||||
|
|
||||||
Principle: provider core and generator logic are universal for all stands and
|
Principle: provider core and generator logic are universal for all stands and
|
||||||
services. The ONLY allowed deviations are DATA entries, and they MUST live in
|
services. Service-specific deviations are of two kinds:
|
||||||
exactly two named registries:
|
|
||||||
|
1. **Generated modifiers** — a `modify` op that should become a dedicated modifier
|
||||||
|
resource. The generator (`TOOLS/resource-generator/internal/loader/loader.go`)
|
||||||
|
supports `kind: modifier` with `delete_strategy` (`noop_warn`/`inverse`/`error`)
|
||||||
|
and `idempotency` (`none`/`check_before_run`). The overlay data file
|
||||||
|
`modifiers.yaml` that would drive this is **documented but NOT yet created**;
|
||||||
|
until then, modifiers are hand-written in `provider/internal/resources_core/`.
|
||||||
|
(The legacy registry `serviceSpecificModifiers` in `TOOLS/yaml-generator/main.go`
|
||||||
|
was REMOVED during the 2026-09-23 refactoring.)
|
||||||
|
2. **Doc examples** — named registry:
|
||||||
|
|
||||||
| Registry | File | Declares |
|
| Registry | File | Declares |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| `serviceSpecificModifiers` | `TOOLS/yaml-generator/main.go` | which service `modify` op becomes a modifier resource and its name (key = normalized service name) |
|
|
||||||
| `serviceSpecificDocExamples` | `TOOLS/docs-generator/internal/writers/writers.go` | per-service doc examples, gated on service name + required state/vault keys |
|
| `serviceSpecificDocExamples` | `TOOLS/docs-generator/internal/writers/writers.go` | per-service doc examples, gated on service name + required state/vault keys |
|
||||||
|
|
||||||
Rules:
|
Rules:
|
||||||
|
|
||||||
- Key by stable service NAME (slug), never by raw numeric ID.
|
- Key by stable service NAME (slug), never by raw numeric ID.
|
||||||
- Each entry answers WHAT / WHAT IT DOES / WHY / WHERE (see code comments).
|
- Each entry answers WHAT / WHAT IT DOES / WHY / WHERE (see code comments).
|
||||||
- Adding an exception = editing one of these two registries → visible in diff.
|
- Doc-example exception = editing the named registry above → visible in diff.
|
||||||
|
- Modifier exception (until `modifiers.yaml` exists) = hand-written resource in
|
||||||
|
`provider/internal/resources_core/` + registration in `provider.go`.
|
||||||
- Never annotate API-YAML: it is machine-regenerated and edits would be lost.
|
- Never annotate API-YAML: it is machine-regenerated and edits would be lost.
|
||||||
|
|
||||||
Enforced by scripts (run before build/commit):
|
Enforced by scripts (run before build/commit):
|
||||||
|
|||||||
Reference in New Issue
Block a user