From 047d53a67b5e6b061b7cb4b3a75ab5cb804b5893 Mon Sep 17 00:00:00 2001 From: Repinoid Date: Wed, 30 Sep 2026 20:32:29 +0300 Subject: [PATCH] =?UTF-8?q?docs(architecture):=20=D0=BF=D1=80=D0=B8=D0=B2?= =?UTF-8?q?=D0=B5=D1=81=D1=82=D0=B8=20TOOLS/ARCHITECTURE.md=20=D0=B2=20?= =?UTF-8?q?=D1=81=D0=BE=D0=BE=D1=82=D0=B2=D0=B5=D1=82=D1=81=D1=82=D0=B2?= =?UTF-8?q?=D0=B8=D0=B5=20=D1=81=20=D0=BA=D0=BE=D0=B4=D0=BE=D0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 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' -> один реестр + ручные ресурсы. --- TOOLS/ARCHITECTURE.md | 53 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 42 insertions(+), 11 deletions(-) diff --git a/TOOLS/ARCHITECTURE.md b/TOOLS/ARCHITECTURE.md index dbae4d8..0a3d12f 100644 --- a/TOOLS/ARCHITECTURE.md +++ b/TOOLS/ARCHITECTURE.md @@ -9,8 +9,10 @@ reflected here FIRST, then implemented in `gen_v2` and other tools. ## Core Principles 1) YAML per service is generated ONLY from API data. -2) The provider core is universal and must not contain service-specific logic. -3) Service-specific Go code is fully generated from YAML. No manual edits. +2) The provider core (`provider/internal/core`) is universal and must not contain + 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. 5) Build artifacts for 3 OS targets are published to the registry, and docs are published to the website. @@ -107,15 +109,23 @@ Each operation has a kind: ## Provider Model -- Core is universal: no service-specific logic inside the core. -- Generated service resources contain only schema/params and references. +- Core (`provider/internal/core`) is universal: no service-specific logic inside it. +- 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 - Core MUST retry transient 401 errors from Gateway (3 attempts, exponential backoff). Gateway may temporarily reject valid JWT tokens. -- GET operations (GetInstanceState, GetInstanceStateRaw) retry 401 with 2s/4s/8s backoff. -- `doRequest` treats 401 as retryable for GET requests (alongside 429, 502, 503, 504). +- **CURRENTLY NOT IMPLEMENTED** — `isRetryable` (`core/http.go`) retries only + {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 @@ -208,28 +218,49 @@ From the unified YAML, generate: 5) Upload provider artifacts to registry. 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 - 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. ## Exception Registry (service-specific DATA, never logic) 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 -exactly two named registries: +services. Service-specific deviations are of two kinds: + +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 | |---|---|---| -| `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 | Rules: - Key by stable service NAME (slug), never by raw numeric ID. - 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. Enforced by scripts (run before build/commit):