@onlineapps/conn-orch-validator 9.0.0 → 11.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +546 -0
- package/README.md +337 -19
- package/docs/DESIGN.md +32 -9
- package/manifests/biz-service.manifest.json +56 -6
- package/package.json +3 -2
- package/src/CookbookTestRunner.js +134 -22
- package/src/ValidationOrchestrator.js +312 -73
- package/src/cli/biz-ci-gate.js +191 -15
- package/src/cli/oa-sync-template.js +23 -8
- package/src/cli/oa-validate.js +70 -2
- package/src/index.js +21 -13
- package/src/lint/scripts/lintScripts.js +65 -18
- package/src/manifest/checks/composeRunnerBlock.js +37 -20
- package/src/manifest/checks/discoveryOrphan.js +2 -1
- package/src/manifest/checks/docsLintBridge.js +79 -21
- package/src/manifest/checks/gitTracked.js +14 -28
- package/src/manifest/checks/libraryPackage.js +3 -1
- package/src/manifest/checks/libraryWorkspace.js +18 -3
- package/src/manifest/checks/readmeRegion.js +9 -1
- package/src/manifest/checks/serviceConfig.js +29 -12
- package/src/manifest/checks/serviceDb.js +176 -7
- package/src/manifest/checks/serviceFiles.js +34 -7
- package/src/manifest/checks/serviceIdentityRows.js +3 -1
- package/src/manifest/checks/serviceRuntime.js +126 -1
- package/src/manifest/discovery.js +25 -7
- package/src/manifest/gitCheckout.js +84 -0
- package/src/manifest/runManifest.js +58 -7
- package/src/manifest/workspaceRoot.js +91 -5
- package/src/sync/serviceTemplate.js +76 -7
- package/src/sync/sharedEnv.js +11 -4
- package/src/sync/uniformFiles.js +91 -21
- package/src/utils/bizCiGateContract.js +25 -1
- package/src/utils/dbAccountGrants.js +126 -0
- package/src/utils/envContract.js +36 -6
- package/src/utils/envReads.js +102 -0
- package/src/utils/installContract.js +46 -5
- package/src/utils/libCompat.js +39 -19
- package/src/utils/preValidation.js +56 -11
- package/src/utils/stepFailure.js +106 -19
- package/src/utils/stepReferences.js +278 -0
- package/src/utils/testCoverageContract.js +60 -2
- package/src/utils/throwawaySchema.js +92 -7
- package/src/validatorIdentity.js +31 -0
- package/src/validators/ServiceStructureValidator.js +47 -15
- package/src/validators/ValidationProofGenerator.js +73 -34
- package/templates/business-service/.dockerignore +9 -1
- package/templates/business-service/.gitlab-ci.yml +199 -35
- package/templates/business-service/Dockerfile +49 -16
- package/templates/business-service/README.md +56 -9
- package/templates/business-service/config/env-templates/__SERVICE_NAME__.env +17 -5
- package/templates/business-service/config/env-templates/shared.env +8 -2
- package/templates/business-service/docker-compose.production.yml +9 -0
- package/templates/business-service/docker-compose.yml +17 -0
- package/templates/business-service/docs/80-setup/PLATFORM_MATRIX.md +1 -1
- package/templates/business-service/docs/80-setup/VALIDATION.md +1 -1
- package/templates/business-service/jest.config.js +9 -1
- package/templates/business-service/package.json.template +1 -1
- package/src/mocks/MockStorage.js +0 -188
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,552 @@ All notable changes to this package. Follows [Keep a Changelog](https://keepacha
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
## [11.0.0] — 2026-09-17
|
|
8
|
+
|
|
9
|
+
### Changed — deploy job aplikuje seedy třídy PRODUCTION_LIKE (d.589, W589)
|
|
10
|
+
|
|
11
|
+
`templates/business-service/.gitlab-ci.yml` (blok `oa-ci v1`): po migracích a před přepnutím se aplikují deklarované
|
|
12
|
+
`database.seeds`, jejichž hlavička nese `Dataset-Class: PRODUCTION_LIKE` (standard `repository-installation-sql-contract.md`
|
|
13
|
+
§4/§5; converter po 10 migracích měl 22 prázdných tabulek). Filtr běží na runneru — box neparsuje JSON ani hlavičky a o třídě
|
|
14
|
+
nerozhoduje; `TEST_ONLY` se nikdy neaplikuje a job to řekne jménem souboru. Seedy se netrackují a jedou při každém nasazení,
|
|
15
|
+
licencí je `-- Idempotency: yes`, její absence i třída mimo slovník odmítnou nasazení před ssh. Devátý poziční argument
|
|
16
|
+
`BIZ_DB_SEEDS`; na boxu `apply_mariadb_seeds_over_tcp <host> <port> <db> <file>...` z běžce neseného z klonu api
|
|
17
|
+
(INFRA `7045a736`), s pojmenovaným odmítnutím mezi předpoklady, když ho klon nenese. Bats `biz-deploy-db-migrations.bats` 24 → 29.
|
|
18
|
+
|
|
19
|
+
### Fixed — box se resetuje na commit, který runner měřil (d.589b, W589)
|
|
20
|
+
|
|
21
|
+
Desátý poziční argument `$CI_COMMIT_SHA`; `git merge-base --is-ancestor` + `git reset --hard "$COMMIT_SHA"` místo
|
|
22
|
+
`origin/production` — push během běhu jobu dosud rozešel to, co runner četl v kontraktu, s tím, co box nasadil.
|
|
23
|
+
|
|
24
|
+
### Fixed — existence `../shared.env` a `config/env-active/<svc>.env` se ověřuje pro každou službu (d.589c, W589)
|
|
25
|
+
|
|
26
|
+
Dosud jen ve větvi s migracemi; služba bez databáze (pdfgen, hello) se o chybějícím souboru dozvěděla až od
|
|
27
|
+
`docker compose`. Kontrola je před větvením s `Fix:` na runbook, který ty dva soubory zakládá
|
|
28
|
+
(`docs/operations/production-box-provisioning.md` § 3).
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
### Added — řádek uniformy `R-USER` (check `process-identity`) (d.588c, W588)
|
|
32
|
+
|
|
33
|
+
Produkční stage `Dockerfile` deklaruje `USER node` a uzel služby v `docker-compose.yml` pinuje `user: "1000:1000"`. Druhý
|
|
34
|
+
platformní fakt vyjmutý ze třídy `own` (prvním je node major, `R-NODE`); běžec drží `F-RUNNER`, produkční compose `G-PROD`
|
|
35
|
+
(kontrolní případy, že `R-USER` mlčí, kde hlásí ten druhý). Zčervená u všech osmi služeb — vždy jedním nálezem o `Dockerfile`
|
|
36
|
+
(dev compose už `user:` má 8/8). `doc` = `docs/biz/00-model/service-shape.md` (vzor `R-PORTS-DEV`); sekce „Process identity"
|
|
37
|
+
v README šablony, generovaná oblast řádků přegenerována.
|
|
38
|
+
|
|
39
|
+
### Fixed — krok, který spadl výjimkou, nechá svůj záznam; nález nese krok (d.602, W602)
|
|
40
|
+
|
|
41
|
+
Wrapper 9.0.x rozhoduje o opakování padlé FÁZE 0.2 podle `result.steps.<krok>.valid`; krok, jehož tělo vyhodilo výjimku, ale
|
|
42
|
+
záznam nezanechal, došel k wrapperu jako „validator spadl" = přechodně, a koupil si šest pokusů (18,5 min bootu, který uspět
|
|
43
|
+
nemůže). `runStep()` je síť pod všemi sedmi kroky: zapíše `{ valid: false, success: false, threw: true, errors: […] }` s tím,
|
|
44
|
+
co krok naměřil, a nález `{ type: 'STEP_THREW', step, message }`; objektové nálezy kroku 1 nesou v `result.errors` `step`
|
|
45
|
+
(kopie). Věty kroků 2–7 zůstávají větami — `describeValidationFinding()` vydaného wrapperu vykreslí objekt jen s `type` i
|
|
46
|
+
`message`; sjednocení na objekty čeká na wrapper, který `errors[].step` čte (pak 11.0.0). `attributeToStep()` odmítne nálezy,
|
|
47
|
+
které nejsou pole, hláškou §5. Krok 5 hlásí `success`, ostatní `valid` — dvě pole pro jeden pojem, zapsáno jako nález.
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
### Changed — BREAKING: šablona biz služby — produkce běží jako uid 1000, běžec má vlastní `conn-runtime` (d.588, W588)
|
|
51
|
+
|
|
52
|
+
`templates/business-service/Dockerfile`: obě stage deklarují `USER node` (uid 1000/gid 1000 v `node:24-alpine`) a zakládají
|
|
53
|
+
`/app/logs` + `/app/conn-runtime` pod tím účtem (`COPY --chown=node:node`). Produkční obraz dosud běžel jako root (změřeno
|
|
54
|
+
`docker run --rm <obraz> id` → `uid=0`), zatímco dev kontejner jako 1000:1000 — asymetrie, kterou nikdo nedeklaroval.
|
|
55
|
+
`docker-compose.production.yml`: `user: "1000:1000"` shodně s dev → řádek `G-PROD` u každé služby zčervená do
|
|
56
|
+
`oa-sync-template docker-compose.production.yml`. Blok `oa-test-runner v1` v `docker-compose.yml` dostal anonymní svazek
|
|
57
|
+
`/app/conn-runtime`, aby proof běžce nepřepisoval proof služby (změřeno converterem: běžec nad `.:/app` zapsal
|
|
58
|
+
`validation-proof.json` běžící instance) → řádek `F-RUNNER` zčervená do `oa-sync-template docker-compose.yml`. Nové sady
|
|
59
|
+
`templateProcessIdentity`, `templateRunnerRuntime`, `templateImageIdentity.integration` (skutečný `docker build` + `docker run`;
|
|
60
|
+
bez démona/checkoutu/registry NOT RUN s důvodem, nikdy červená za síť).
|
|
61
|
+
|
|
62
|
+
### Changed — BREAKING: šablona neměří uniformu při buildu obrazu — verdikt patří CI (d.588b, W588)
|
|
63
|
+
|
|
64
|
+
Řádek `RUN … oa-validate.js .` ve stage `production` (d.215b, `4b5ed9e6`) měřil uniformu nad build kontextem bez `.git`,
|
|
65
|
+
compose a README — u každé reálné služby (`.dockerignore` je správně vyřazuje) `NOT DEPLOYABLE — 10 finding(s)`, všechny
|
|
66
|
+
„absent", a build spadl. Konfirmace 006/2 („information, never a gate"), 010 (`validate-uniform` z každého commitu nad
|
|
67
|
+
checkoutem) a 011 (strom bez git checkoutu = NOT RUN) větu 001 §3.1 překonaly; řádek je pryč i s testem `add-service.bats`
|
|
68
|
+
54, který teď tvrdí opak. `templateImageIdentity` už nepotřebuje srovnat scaffold pinovanou verzí (19 s místo 46 s).
|
|
69
|
+
|
|
70
|
+
### Fixed — fixtury uniformy dosynchronizovány na SSOT sdílené sady (dovětek d.533, W588)
|
|
71
|
+
|
|
72
|
+
14 fixtur `shared.env` a 3 `shared-env.json` se od `f61501cc` lišily jedním klíčem (`JWT_SECRET` `why`/`consumers`);
|
|
73
|
+
`manifestServiceConfig` (`G-SHARED-ENV`) byla proto v HEAD červená. Záměrně rozejitá `service-workspace/api_biz/beta`
|
|
74
|
+
zůstala (vstup případu „not the platform manifest rendered").
|
|
75
|
+
|
|
76
|
+
### Changed — BREAKING: krok 7 mimo git checkout je NOT RUN, ne „NOT DEPLOYABLE" (d.592, W592)
|
|
77
|
+
|
|
78
|
+
Produkční obraz není checkout a nenese compose ani README, takže uniforma měřená tam hlásila 12 nálezů nepřítomnosti a
|
|
79
|
+
služba se registrovala `deployable: false` (BIZ-pdfgen 2026-09-16). Verdikt z toho není přísnost, ale špatná odpověď:
|
|
80
|
+
krok vypíše jednu větu NOT RUN s odkazem na CI job `validate-uniform`, `results.deployable` zůstává `null` (= neměřeno,
|
|
81
|
+
jiné tvrzení než `false`), banner ani `ci/deployability.json` nevznikají (konfirmace `biz-service-manifest` 010, 011).
|
|
82
|
+
Sonda `git ls-files` má jedno místo `src/manifest/gitCheckout.js` (`gitCommand`, `listTrackedFiles`, `isGitCheckout`,
|
|
83
|
+
věta `NOT_A_CHECKOUT`); `X-IGNORED` ji bere odtud. Fixtury kroku 7 jsou nově checkouty přes `makeGitCheckout`.
|
|
84
|
+
|
|
85
|
+
### Added — Tier-1 běžec předává výstup kroku dalším krokům (d.590, W590)
|
|
86
|
+
|
|
87
|
+
`{{steps.<step_id>.output.…}}` v `input` kroku se rozřeší proti tomu, co dřívější kroky téhož receptu vrátily, takže recept
|
|
88
|
+
si fixturu vytvoří, použije a smaže (vlastník: konfirmace `converter-boot-cookbook` 001 — „opravit v knihovně"). Syntaxe
|
|
89
|
+
i průchod zůstávají cookbook formátu a `@onlineapps/cookbook-core` (`resolveReferencesWith`, `resolveReferencePath` —
|
|
90
|
+
táž kolej jako `WorkflowOrchestrator`); běžec přidává jen scope běhu (`src/utils/stepReferences.js`) tvaru `format.md`
|
|
91
|
+
§ Runtime context (`context.steps`): definice kroku + `output` + `_execution`, adresováno `step_id`. Expanduje se jen
|
|
92
|
+
`input`; `output` se zapisuje jen u kroku, který prošel; scope je per cookbook. `CookbookTestRunner.executeStep()` má
|
|
93
|
+
pátý parametr (kontext běhu; samostatný krok dostane prázdný). Po spadlém kroku s `expect` se další kroky nepouští
|
|
94
|
+
(dnešní chování, nově připnuté testem). NOVÁ ZÁVISLOST: `@onlineapps/cookbook-core` (SSOT) — do `dependencies` před vydáním.
|
|
95
|
+
|
|
96
|
+
### Added — Tier-1 běžec odmítá recept, který produkce nepřijme (d.598, W598)
|
|
97
|
+
|
|
98
|
+
Před během: volání template helperu v `input` (`jméno(...)` — Tier-1 registr helperů nemá a `cookbook-template-helpers`
|
|
99
|
+
táhne `content-resolver`, tedy I/O), `{{steps.<id>}}` na krok, který recept nedefinuje (včetně tečkového `{{steps.0}}`;
|
|
100
|
+
gateway odpovídá 400, konfirmace `cookbook-validation-placement` 001 = throw u příjemce jako pojistka), a `depends_on` na
|
|
101
|
+
nedefinovaný krok. Dosud obojí tiše propadlo jako literál. `utils/stepReferences.checkStepInputExpressions()` používá týž
|
|
102
|
+
`resolveReferencesWith()`. Literálem zůstává, co jím podle normy být má (`{{steps[0]}}`, `{{api_input.…}}`, `{{context.…}}`,
|
|
103
|
+
`{{current.…}}`, odkaz na definovaný, ale neběžící/selhavší krok). Dopad na dnešní recepty služeb: 0 ze 43.
|
|
104
|
+
|
|
105
|
+
### Fixed — `MISSING_COOKBOOKS` nese `Fix:` právě jednou (d.599, W598)
|
|
106
|
+
|
|
107
|
+
Jediný ze 17 nálezů `ServiceStructureValidator` měl nápravu i uvnitř `message`; wrapper 9.0.1 složením `message (Fix: fix)`
|
|
108
|
+
ji tiskl dvakrát.
|
|
109
|
+
|
|
110
|
+
### Added — `oa-validate --env-reads [<serviceRoot>]` (d.533c, W533c)
|
|
111
|
+
|
|
112
|
+
Vypíše jména proměnných prostředí, která služba čte: po řádcích, seřazená, bez duplicit, nic jiného (žádný banner, žádný
|
|
113
|
+
verdikt, žádné `ci/deployability.json`), exit 0; bez čitelného `config/service/integration-contract.json` exit 2 a
|
|
114
|
+
`[oa-validate] … Fix: …` na stderr; nekombinuje se s `--json`, `--library`, `--all`, `--workspace`. Odpovídá bráně nasazení
|
|
115
|
+
`api/scripts/validate-env.sh`, která u biz cíle shazovala nasazení na `JWT_SECRET=CHANGE_ME` — klíč, který žádný biz obraz
|
|
116
|
+
nečte (dohoda s INFRA 2026-09-17). `utils/envContract.js` vystavuje `collectDeclaredEnvNames({serviceRoot, contract})` —
|
|
117
|
+
množina, proti které měří řádek `C-ENV-READS` (`env` blok ∪ `${VAR}` z `config/service/*.json` ∪ endpointové proměnné
|
|
118
|
+
vyžadovaných konektorů), vytažená z `verifyEnvCompleteness`, aby druhý konzument nezaložil druhou definici.
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
### Documentation — zabalený `shared.env` nese komentář u `JWT_SECRET` podle SSOT (d.533)
|
|
122
|
+
|
|
123
|
+
Šablona `templates/business-service/config/env-templates/shared.env` je render SSOT `api/config/shared-env.json`; `why` u `JWT_SECRET`
|
|
124
|
+
teď jmenuje čtyři infra čtenáře a říká, že business řetězec klíč nese a nečte (`@onlineapps/service-common` bere tajemství jako vstup).
|
|
125
|
+
Vydání 10.0.0 (22:32) přistálo o čtyři minuty dřív než `f61501cc` — zabalená kopie je o tento komentář pozadu, chování beze změny.
|
|
126
|
+
|
|
127
|
+
### Added — CI pod účtem služby (d.567)
|
|
128
|
+
|
|
129
|
+
Nový příkaz `oa-biz-ci-gate setup-db-account`: založí účet, který služba **deklaruje** (`DB_USER`
|
|
130
|
+
v `config/env-templates/<služba>.env` — týž klíč, který měří řádek `D-DB-ACCOUNT`), a udělí mu granty na
|
|
131
|
+
jeho schéma. Je to **jediný** krok biz pipeline pod rootem databáze a poslední takový: všechno za ním
|
|
132
|
+
se připojuje jako služba, stejně jako produkce. Důvod je konfirmace `db-migrations-first-deploy` 001
|
|
133
|
+
(„migrace nikdy pod rootem"): sedm pipeline dnes aplikuje tutéž migrační sadu pod `DB_USER: "root"`,
|
|
134
|
+
takže CI dokazuje průchod migrací právy, která produkce neuděluje.
|
|
135
|
+
|
|
136
|
+
Věty SQL mají **jednu definici** — `src/utils/dbAccountGrants.js`. Produkční runbook a CI jsou dva
|
|
137
|
+
volající, ne dvě kopie (`db-migrations-first-deploy` 001: „žádný nový generátor SQL, žádná druhá kolej").
|
|
138
|
+
Jediný rozdíl CI proti produkci je grant na zahazovací jmenný prostor `` `<schéma>\_%` `` (staví do něj
|
|
139
|
+
integrační tier, `throwawaySchema.js`); `_` je escapované, takže grant zůstává uvnitř jedné služby —
|
|
140
|
+
neescapovaný je `_` zástupný znak LIKE a `oagen_meta_%` by sáhlo i na `oagen_metadata`.
|
|
141
|
+
`GRANT … ON information_schema.*` v sadě **není**: server ho odmítá i rootu (změřeno na dev
|
|
142
|
+
`gen_mariadb10.5`, MariaDB 10.5.17, `ERROR 1044`), a každý účet ten katalog čte filtrovaně sám.
|
|
143
|
+
|
|
144
|
+
Rootové přihlášení má vlastní jména `CI_DB_ROOT_USER` / `CI_DB_ROOT_PASSWORD` a nebere se z `DB_USER`
|
|
145
|
+
(`architecture-principles.md` §8) — právě to, že ty dvě identity byly jedna hodnota, příkaz končí.
|
|
146
|
+
Heslo účtu je zahazovací hodnota jobu (`DB_PASSWORD`), nikdy `CHANGE_ME` ze šablony: šablona deklaruje
|
|
147
|
+
klíč, ne tajemství. Služba bez bloku `database` hlásí `NOT APPLICABLE` a končí nulou, jako `setup-db`.
|
|
148
|
+
Žádné heslo se na výstup nedostane ani na cestě selhání.
|
|
149
|
+
|
|
150
|
+
Že ty granty **stačí** — a pořád nejsou příliš — není vlastnost textu SQL, ale odpovědi serveru, takže je
|
|
151
|
+
to změřeno proti skutečné MariaDB (dev `gen_mariadb10.5`, 10.5.17): se samotným produkčním grantem server
|
|
152
|
+
stavbu zahazovacího schématu odmítne (`ERROR 1044`), po `setup-db-account` projde, a účet přitom pořád
|
|
153
|
+
nedosáhne na sousední službu — ani na její schéma, ani na zahazovací schéma v jejím jmenném prostoru, ani
|
|
154
|
+
na řádky, ani na její jméno v katalogu. Soused se jmenuje `<ns>ax` k `<ns>a` právě proto, že neescapované
|
|
155
|
+
`_` by ho pustilo dovnitř.
|
|
156
|
+
|
|
157
|
+
Kaskáda: sedm repozitářů s databází přepíše v jobu `test` `DB_USER: "root"` na účet služby a zařadí
|
|
158
|
+
`setup-db-account` před `ci:gate:setup`.
|
|
159
|
+
|
|
160
|
+
### Added — řádek uniformy `D-DB-CI-ACCOUNT` (d.567)
|
|
161
|
+
|
|
162
|
+
`D-DB-ACCOUNT` měří deklaraci (`DB_USER` v šabloně prostředí); nic neměřilo prostředí, ve kterém se ta
|
|
163
|
+
migrační sada každý den skutečně aplikuje. Nový řádek (`severity: deploy`, vlastník BIZ-general) hlásí
|
|
164
|
+
`DB_USER` s hodnotou `root` a `ci:gate:setup`, před kterým neběží `setup-db-account`. Samostatný řádek,
|
|
165
|
+
ne rozšíření `D-DB-ACCOUNT`: jiný soubor, jiná oprava, a jeden řádek se dvěma opravami jsou dva
|
|
166
|
+
mechanismy pod jedním jménem (`automation-gates.md` §1.2). Čte řádky **mimo** blok `oa-ci v1` (ten je
|
|
167
|
+
G-CI), takže nekřísí problém, kvůli kterému byl celosouborový řádek nad `.gitlab-ci.yml` po třech dnech
|
|
168
|
+
stažen.
|
|
169
|
+
|
|
170
|
+
Měří, KDO kroky nad databází pouští, a záměrně ne, ZDA je repozitář pouští: job, který nestaví schéma,
|
|
171
|
+
nemá účet, který by tento krok zakládal. Hranice je napsaná, protože nevyslovená hranice se čte jako
|
|
172
|
+
pokrytí (`automation-gates.md` §5). Obě pravopisné podoby téhož: `DB_USER: "root"` v `variables:` i
|
|
173
|
+
`DB_USER=root` jako předřazené přiřazení na samotném kroku (změřený tvar `api_biz/hello-service`).
|
|
174
|
+
Komentář, který jmenuje `ci:gate:setup`, krokem není (změřený tvar `api_biz/meta`).
|
|
175
|
+
|
|
176
|
+
Změřeno nad všemi osmi repozitáři: sedm hlásí dva nálezy s číslem řádku a proveditelnou opravou,
|
|
177
|
+
`pdfgen` (bez bloku `database`) mlčí z konstrukce. Zrcadla generovaného seznamu řádků (README uniforma
|
|
178
|
+
šablony i všech fixtur, `api/templates/business-service/README.md`) přegenerována v témže commitu.
|
|
179
|
+
|
|
180
|
+
## [10.0.0] — 2026-09-16
|
|
181
|
+
|
|
182
|
+
### Removed — `MockStorage` (d.583)
|
|
183
|
+
|
|
184
|
+
Dvojník bez konzumenta (po d.576) smazán i se souborem a vlastním testem; `MockMQClient`/`MockRegistry` zůstávají
|
|
185
|
+
(interní čtenáři), povrch exportů beze změny (17 jmen).
|
|
186
|
+
|
|
187
|
+
### Changed — `tests/cookbooks` je podmínka bootu, ne doporučení (d.584)
|
|
188
|
+
|
|
189
|
+
Chybějící nebo prázdný adresář = error `MISSING_COOKBOOKS` (severity boot; orchestrátor fail-fast na kroku 1) místo dvou
|
|
190
|
+
warningů, které nechaly absenci projít až k odmítnutému důkazu. `tests/unit`/`tests/integration` zůstávají doporučením
|
|
191
|
+
(uniforma jejich existenci nevymáhá). Jedna kolej s F-DOCKERIGNORE (`!tests/cookbooks`). Kaskáda: žádná — 8/8 služeb recepty má.
|
|
192
|
+
|
|
193
|
+
### Changed — F-DOCKERIGNORE vylučuje testovací strom, `tests/cookbooks` zůstává v obrazu (d.560)
|
|
194
|
+
|
|
195
|
+
`tests/` všech 8 služeb jelo do produkčního obrazu (`COPY . .`, ingest 632 K). Pravidlo `dockerignoreEntries()` = gitignore ∪
|
|
196
|
+
{`tests`, `**/tests`} ∖ {`tests/cookbooks`}: testy do artefaktu nepatří (analogie `L-PACK-TESTS`), cookbooky jsou deklarace
|
|
197
|
+
Tier-1, které boot čte ve fázi 0.2 — obraz bez nich nenaběhne (`ValidationProofGenerator` odmítne důkaz s `testsRun 0`).
|
|
198
|
+
Blok `oa-dockerignore v1` je výstup pravidla; ověřeno skutečným buildem (BuildKit `!tests/cookbooks`). Běžec netrpí (bind mount).
|
|
199
|
+
Kaskáda: služby přegenerují `.dockerignore` (`oa-sync-template`).
|
|
200
|
+
|
|
201
|
+
### Fixed — šablona `jest.config.js` má `testTimeout` 120 000 ms (d.580)
|
|
202
|
+
|
|
203
|
+
30 s na sdíleném dev stroji (load 47–94, běžci víc služeb) shazovalo `beforeAll` sad, které samostatně projdou (BIZ-converter);
|
|
204
|
+
limit má chytat zaseknutý test, ne frontu na procesor. `maxWorkers: 1` beze změny (konf `biz-memory-limits` 001). Řádek F-JEST
|
|
205
|
+
generovaný → služby přegenerují `jest.config.js`.
|
|
206
|
+
|
|
207
|
+
### Removed — koncept `mockInfrastructure` (d.576)
|
|
208
|
+
|
|
209
|
+
Volba konstruktoru `CookbookTestRunner` i pole `test.mockInfrastructure` v receptu se odmítají JMÉNEM (hlášky s `Fix:`,
|
|
210
|
+
recept navíc se jménem souboru); `src/index.js` nepublikuje `MockMQClient`/`MockRegistry`/`MockStorage` ani `createMock*`
|
|
211
|
+
(surface 23 → 17 jmen). Krok se dispatchuje in-process proti vlastnímu v3 handleru, DB je skutečná — `this.mqClient`/
|
|
212
|
+
`this.registry` nikdo nečetl, mimo balíček 0 konzumentů (konf `declaration-removal` 001). Nahrazuje řádek „Documentation —
|
|
213
|
+
`mockInfrastructure` staví nápodobu MQ a registry" (d.521). DOPAD kaskády: recepty s tím polem (converter `ping.json`, meta 2,
|
|
214
|
+
hello 12) a volba v bootstrap testech (converter, ingest, hello, emailer) prevalidaci shodí, dokud služba pole neodstraní.
|
|
215
|
+
|
|
216
|
+
### Fixed — agregát běhu sčítá jen změřené hodnoty (d.576b)
|
|
217
|
+
|
|
218
|
+
`results.totalTests/passedTests/failedTests` přes `readStepMeasurement()`; `|| 0` byl zdroj neměřené nuly, kvůli které
|
|
219
|
+
odmítnutí generátoru (d.524) nikdy nevystřelilo. Změřená nula zůstává nulou. Smazán mrtvý `createEncodedProof` v testu.
|
|
220
|
+
|
|
221
|
+
### Fixed — throwaway schéma odmítne příkaz kvalifikovaný cizím schématem (d.538)
|
|
222
|
+
|
|
223
|
+
`<schema>.<tabulka>` jiného než throwaway schématu poslal příkaz testu do živého schématu (změřeno: řádek přistál v živé
|
|
224
|
+
tabulce). Jediná výjimka je read-only `information_schema` (22 živých migrací ve 4 repech). Úvodní `USE` se dál stripuje —
|
|
225
|
+
standard `repository-installation-sql-contract.md` o `USE` neříká nic; zpřísnění patří vlastníkovi standardu.
|
|
226
|
+
|
|
227
|
+
### Fixed — hlavičková brána instalačního kontraktu kryje i `database.seeds` mimo `migrations/**` (d.541)
|
|
228
|
+
|
|
229
|
+
Konf `installation-sql-contract-scope` 003: rozsah hlavičky je, co instalátor aplikuje. Deklarovaný chybějící seed =
|
|
230
|
+
nález, ne ENOENT. Změřeno nad 8 repy: žádné nezčervená (ingest opravil `bfd04b9`).
|
|
231
|
+
|
|
232
|
+
### Fixed — každá NOT RUN věta nese nápravu, padlý recept své jméno, `docsLintBridge.js` je zase text (d.523)
|
|
233
|
+
|
|
234
|
+
`biz-ci-gate.js` hlásil u odmítnutého receptu `step_id: undefined`; 5× `describeNotRun` a `runManifest` bez `Fix:` →
|
|
235
|
+
jeden vlastník `describeWorkspaceFix`; duplicitní blok a NUL v `docsLintBridge.js`; `uniformFiles.js` lepil druhý `Fix:`.
|
|
236
|
+
`biz-ci-gate.js` má mód 755 jako ostatní CLI (`bin` + shebang).
|
|
237
|
+
|
|
238
|
+
### Changed — validační důkaz píše výhradně `ValidationProofGenerator`, i na bootovací cestě (d.524)
|
|
239
|
+
|
|
240
|
+
Druhá kolej v `ValidationOrchestrator` mohla zapsat důkaz s `testsRun: 0`; jméno a verze validátoru se čtou z vlastního
|
|
241
|
+
`package.json` a nelze je přebít (`validatorVersion || '1.0.0'` pryč). Služba bez receptů v `tests/cookbooks/` validaci
|
|
242
|
+
neprojde (dřív psala důkaz, který registry stejně odmítl jako NO_TESTS) — všech 8 biz rep recepty má.
|
|
243
|
+
|
|
244
|
+
### Removed — `ValidationProofGenerator.createValidationError()` (d.524)
|
|
245
|
+
|
|
246
|
+
Bez konzumentů.
|
|
247
|
+
|
|
248
|
+
### Fixed — ctx Tier-1 běžce nese `step_id`, jako produkční `OperationContext` (d.549)
|
|
249
|
+
|
|
250
|
+
Content-resolver 4.0.1 `createDescriptor` bez `step_id` odmítá; producent tak mohl přejít na `ctx.step_id` až teď (BIZ-pdfgen).
|
|
251
|
+
|
|
252
|
+
### Documentation — balíčková kopie `shared.env` má čtenáře; zapsáno k otázce d.536 (d.557)
|
|
253
|
+
|
|
254
|
+
`renderTree` → `oa-sync-template template` → `templateMirror` drží zrcadlo `api/templates/business-service` byte za bytem; zrcadlo
|
|
255
|
+
čtou `biz-deploy-uniform-gate.bats:165` (kopie do fixtury), `redis-requirepass.bats:51,55,164` (kontrakt `REDIS_URL`) a
|
|
256
|
+
`shared-env-sync.bats`. d.536 ukončilo jen čtení VERDIKTEM (`G-SHARED-ENV` renderuje SSOT, `runNew` přepisuje živým renderem).
|
|
257
|
+
Soubor zůstává, šablona má dál 25 souborů.
|
|
258
|
+
|
|
259
|
+
### Added — řádky `S-UNIT-C` a `S-COOK-C`: každý běžcový skript šablony má svůj řádek (d.527)
|
|
260
|
+
|
|
261
|
+
Šablona nesla `test:container` a `test:cookbooks:container` bez řádku manifestu, converter měl `test:bootstrap/unit/integration/
|
|
262
|
+
all/cookbooks:container`, property žádný `*:container` — mapa vydání jmenovala příkaz, který ve službě neexistoval (BIZ-converter
|
|
263
|
+
nález 25). Šablona = výstup řádků: `test:unit:container` (`S-UNIT-C`), `test:cookbooks:container` (`S-COOK-C`) vedle `S-ALL-C`/`S-INT-C`;
|
|
264
|
+
výjimka pro běžcový skript bez řádku zrušena. Kaskáda: 5 služeb přejmenuje `test:container` → `test:unit:container`, hello a pdfgen doplní
|
|
265
|
+
`test:cookbooks:container`.
|
|
266
|
+
|
|
267
|
+
### Changed — env šablona služby nedeklaruje `SERVICE_NAME` (d.539)
|
|
268
|
+
|
|
269
|
+
Identitu vlastní `config/service/config.json` (`ServiceWrapper._serviceName()`, předává se do `MonitoringConnector.init({serviceName})`);
|
|
270
|
+
klíč v env nečetl nikdo, emailer a pdfgen bez něj běží (BIZ-emailer, BIZ-invoicing). Komentář k `MARIADB_MIGRATION_USER/PASSWORD` říká
|
|
271
|
+
hostitelský kontrakt (`env-active/<svc>.env` na boxu, konf `db-migrations-first-deploy` 001 fáze 1); README šablony říká, že F-JEST ruší
|
|
272
|
+
lokální `setupFiles` (env bere běžec z `env_file`).
|
|
273
|
+
|
|
274
|
+
### Changed — `oa-sync-template` chybějící blok `init.sh` vloží (d.552)
|
|
275
|
+
|
|
276
|
+
Řádek F-INIT jen hlídal existující blok a chybějící kázal opsat ručně (`BLOCKED … paste the block from the template once`, BIZ-invoicing);
|
|
277
|
+
hláška „udělej to ručně" u generovaného obsahu je defekt. `insertBlockAfterFunction` + `F-INIT.insert_after_function`: bez kotvy odmítne s `Fix:`.
|
|
278
|
+
|
|
279
|
+
### Removed — scaffold už nerenderuje `scripts/verify-deploy-uniform.sh` do služby (d.555)
|
|
280
|
+
|
|
281
|
+
Oba CI joby ho od d.529 volají z pinovaného balíčku; soubor v repu služby nečetl nikdo. `PACKAGE_ONLY` v renderu, zrcadlo
|
|
282
|
+
`api/templates/business-service/scripts/` smazáno; šablona má 25 souborů.
|
|
283
|
+
|
|
284
|
+
### Fixed — `GIT_CLONE_PATH` uniformního běhu má vlastní slot runneru (d.556)
|
|
285
|
+
|
|
286
|
+
`validate-uniform` běží na každém pipelinu; dva souběžné pipeliny na jednom runneru sdílely build adresář →
|
|
287
|
+
`$CI_BUILDS_DIR/oa-uniform/$CI_CONCURRENT_ID/api_biz/<svc>`.
|
|
288
|
+
|
|
289
|
+
### Added — job `validate-uniform` v generovaném bloku `oa-ci v1`: uniforma běží na každém pipelinu (d.529)
|
|
290
|
+
|
|
291
|
+
Konfirmace `biz-service-manifest` 010 (vlastník 2026-09-16): 008 říká, KDE brána musí být před nasazením, ne že
|
|
292
|
+
se jinde nepouští. Job `validate-uniform` (stage `test`, rules MR/main/devel/production) klonuje `api` a spouští
|
|
293
|
+
celou uniformu biz služby; `deploy-production` zůstává závaznou poslední instancí. `secret_detection` běží i na
|
|
294
|
+
`devel`, kam post-commit zrcadlo posílá každý commit (dosud `pipelines?ref=devel` = 0). `build` na `devel` záměrně
|
|
295
|
+
NEběží — 010 žádá kontrolu z každého commitu, ne obraz; `IMAGE_LATEST` z devel by přepsal `latest` platformy.
|
|
296
|
+
|
|
297
|
+
### Changed — oba běhy uniformy volají `verify-deploy-uniform.sh` z pinovaného balíčku (d.529)
|
|
298
|
+
|
|
299
|
+
`scripts/verify-deploy-uniform.sh` neexistoval v žádném z 8 biz repozitářů (jen v šabloně) → `deploy-production`
|
|
300
|
+
padal na prvním kroku `script:`. Oba joby ho volají z `node_modules/@onlineapps/conn-orch-validator/templates/
|
|
301
|
+
business-service/scripts/` — brána i engine z jednoho pinu, žádná kopie do 8 rep; klon `api` přes `$API_CHECKOUT`
|
|
302
|
+
nejde, skript ho sám maže. Rozvržení a runtime obou jobů deklaruje jednou skrytý klíč `.oa-uniform` (`extends`).
|
|
303
|
+
Řádek `G-CI`: `why` přepsáno na dnešní stav (šablona od d.470 nenese `verify-installation-contract:`), `doc` → 010.
|
|
304
|
+
|
|
305
|
+
### Changed — `G-SHARED-ENV` čte SSOT `api/config/shared-env.json` ve workspace, ne render zabalený v balíčku (d.536)
|
|
306
|
+
|
|
307
|
+
Ingest, emailer, hello, invoicing, pdfgen po dovydání 2: řádek porovnával s renderem zabaleným v 9.0.0 (d.229),
|
|
308
|
+
`oa-sync-template shared-env` renderoval z živého SSOT (d.500/d.510) → služba nemohla být zároveň „synced" i
|
|
309
|
+
DEPLOYABLE („10 line(s) differ"). Řádek renderuje SSOT týmž rendererem jako sync; bez dosažitelného workspace
|
|
310
|
+
NOT RUN s `Fix:` (v deploy jobu je `api` naklonované, 008). Kaskáda: každá biz služba po pinu spustí
|
|
311
|
+
`oa-sync-template readme-uniform --target .` (region README nese `from` řádku).
|
|
312
|
+
|
|
313
|
+
### Changed — `oa-validate .` odvozuje kořen workspace od kořene služby (d.540)
|
|
314
|
+
|
|
315
|
+
Z `<workspace>/api_biz/<svc>` bez `--workspace` hlásil validator instalovaný v `node_modules` služby
|
|
316
|
+
`Workspace root: NOT RESOLVED` (kořen hledal jen od balíčku) → U-*/D-* NOT RUN. Třetí otázka: nejbližší předek
|
|
317
|
+
kořene služby s `api/config/services.json`; explicitní `--workspace` dál vyhrává.
|
|
318
|
+
|
|
319
|
+
### Fixed — F-RUNNER porovnává směrem render; zpětná substituce jména služby zrušena (d.531)
|
|
320
|
+
|
|
321
|
+
`normalizeRunnerBlock` nahrazovala jméno služby v bloku zpět na `__SERVICE_NAME__`, takže u služby jménem `meta`
|
|
322
|
+
přepsala i literál v komentáři šablony (`api_biz/meta/docker-compose.yml carries the full numbers`) a řádek hlásil
|
|
323
|
+
nález, zatímco `oa-sync-template docker-compose.yml --check` říkal `unchanged`. Jedna kolej = referenci vyrenderovat
|
|
324
|
+
jménem služby a porovnat (`renderRunnerIdentity`); `normalizeRunnerBlock` smazána (jediný čtenář byl tento řádek).
|
|
325
|
+
|
|
326
|
+
### Changed — důkaz validace odmítá neměřenou nulu; kontrakt odmítá `db: true` bez bloku `database` (d.521)
|
|
327
|
+
|
|
328
|
+
`ValidationProofGenerator.generateProof()` čte `durationMs`, `testsRun`, `testsPassed`, `testsFailed` z agregátu
|
|
329
|
+
runneru JMÉNEM a chybějící měření odmítne místo doplnění `0`; běh, který nic nespustil (`testsRun === 0`), je
|
|
330
|
+
odmítnut u autora, ne až v registru (`ValidationProofCodec.decode()` = NO_TESTS). Integrační kontrakt odmítá
|
|
331
|
+
`requiredConnectors.db: true` bez bloku `database` — směr, který přechodová výjimka F4 nechala otevřený
|
|
332
|
+
(shoda hotová: 7/8 služeb má obojí, pdfgen ani jedno, 0 repozitářů nese `ci-setup-db.js`).
|
|
333
|
+
|
|
334
|
+
### Removed — `ValidationProofGenerator.extractTestSummary()` (d.521)
|
|
335
|
+
|
|
336
|
+
Nula konzumentů od 98d155f1 (2025-09-30); jediné pole nad agregátem, `coverage`, na platformě nic neměří.
|
|
337
|
+
|
|
338
|
+
### Documentation — `mockInfrastructure` staví nápodobu MQ a registry, databázi ne (d.521)
|
|
339
|
+
|
|
340
|
+
README § „What `mockInfrastructure` covers — and what it does not": `run-prevalidation` běží proti skutečnému
|
|
341
|
+
schématu každé služby, která ho deklaruje, a patří až za `ci:gate:setup`; pokrytou množinu připíná test.
|
|
342
|
+
|
|
343
|
+
### Fixed — každá NOT RUN věta nese svou nápravu, každý padlý záznam svou identitu (d.516, d.516b, d.518)
|
|
344
|
+
|
|
345
|
+
Jediný vlastník věty `Fix: run with --workspace pointing at a checkout that carries …` je
|
|
346
|
+
`manifest/workspaceRoot.js` § `describeWorkspaceFix`; berou ji `docsLintBridge` (D-PORT, D-RETIRED, D-LINT),
|
|
347
|
+
`libraryWorkspace.js` § `notRunBecause` (U-ORPHAN, U-MISMATCH, L-PINS, L-CONSUMER, L-TOOLING) a `readmeRegion.js`
|
|
348
|
+
(L-README-REGION). `X-IGNORED` nad stromem bez `.git` jmenuje vlastní nápravu — běh nad klonem, ne nad exportem.
|
|
349
|
+
`results.steps` runneru nese dva druhy záznamů (`kind: step` / `cookbook-load-failure`): odmítnutý recept se hlásí
|
|
350
|
+
jako recept (soubor + chyba), krok bez `step_id` je chyba §5, `validateCookbook` vyžaduje `step_id` jako cookbook-core 5.0.0.
|
|
351
|
+
|
|
352
|
+
### Changed — kontrola se scope vyžadujícím workspace vlastní svou NOT RUN větu (d.518)
|
|
353
|
+
|
|
354
|
+
`runManifest.js` už nepůjčuje výchozí větu „the workspace root is not reachable"; kontrola bez `describeNotRun`
|
|
355
|
+
běh odmítne na každém běhu. Na výchozí větu nedosahovala žádná registrovaná kontrola (`automation-gates.md` §5).
|
|
356
|
+
|
|
357
|
+
### Fixed — `results.steps` říká, co každý záznam je; krok bez `step_id` se neobejde pojmenováním (d.516b)
|
|
358
|
+
|
|
359
|
+
`results.steps` nese dva druhy záznamu a nejsou to oba kroky: výsledek kroku, a záznam, který
|
|
360
|
+
`CookbookTestRunner.runCookbooks` uloží za recept, jejž formátová kontrola odmítla — celý recept, který
|
|
361
|
+
žádný krok nevydal. Splývaly, takže odmítnutý soubor hlásil krok, který neexistuje:
|
|
362
|
+
`cookbook "broken.json" step "step #1": … cookbook format version is missing`. Každý záznam teď svůj druh
|
|
363
|
+
**deklaruje** (`kind: 'step'` / `kind: 'cookbook-load-failure'`) tam, kde vzniká, a nikdo ho nedovozuje
|
|
364
|
+
z chybějícího pole (`architecture-principles.md` §8). Nenačtený recept se hlásí jménem souboru:
|
|
365
|
+
`cookbook "broken.json" could not be run: …`.
|
|
366
|
+
|
|
367
|
+
Teprve na tom stojí druhá polovina: `utils/stepFailure.js` § `describeStepIdentity` **odmítne** záznam
|
|
368
|
+
kroku bez `step_id` místo aby ho pojmenoval pozicí (`step #3 (operation: convert)`). Ta náhrada byla
|
|
369
|
+
správná odpověď, dokud se tvar usazoval — alternativou bylo `undefined`. Dnes je `step_id` povinné od
|
|
370
|
+
`@onlineapps/cookbook-core` 5.0.0 a orchestrátor od d.460 odmítne task krok bez operace
|
|
371
|
+
(`_requireStepOperation`), takže krok bez `step_id` je vadný recept a pravděpodobné jméno ho čte jako
|
|
372
|
+
v pořádku (§3). Pozice zůstává v hlášce — jako to, čím se vadný krok najde, ne jako jeho jméno (§5).
|
|
373
|
+
|
|
374
|
+
`CookbookTestRunner.validateCookbook` nově žádá `step_id` jako první ze tří polí, která cookbook-core 5.0.0
|
|
375
|
+
u task kroku vyžaduje; tím zmizel i `Step ${step.step_id || 'unknown'}` z hlášek o `service`/`operation` —
|
|
376
|
+
případ, který zastupoval, už nenastane. Ověřeno pozitivní kontrolou nad 43 ostrými recepty
|
|
377
|
+
(`api/templates/business-service` + `api_biz/*/tests/cookbooks`): žádný krok bez `step_id`.
|
|
378
|
+
|
|
379
|
+
### Fixed — NOT RUN „workspace není dosažitelný" nese týž Fix (d.516b)
|
|
380
|
+
|
|
381
|
+
`checks/docsLintBridge.js` § `describeNotRun` (obě kontroly) končil u toho, že workspace není — druhý kanál
|
|
382
|
+
vedle toho, který zavřela d.516, a týž nedostatek (`automation-gates.md` §1 požadavek 4). Věta pochází
|
|
383
|
+
z téhož vlastníka, `workspaceRoot.js` § `describeWorkspaceFix`. Ostatní `describeNotRun` (`readmeRegion.js`,
|
|
384
|
+
`libraryWorkspace.js`) a výchozí hláška v `runManifest.js` Fix stále nenesou — nahlášeno, neopraveno.
|
|
385
|
+
|
|
386
|
+
### Fixed — most k dokumentačnímu lintu píše u NOT RUN týž Fix jako chybějící kořen (d.516)
|
|
387
|
+
|
|
388
|
+
`checks/docsLintBridge.js` skládal větu NOT RUN z vlastního textu a končil tam, kde skončil linter:
|
|
389
|
+
`F002:http-ports could not be decided — api_biz/*/docker-compose.yml lives in a sibling checkout this run
|
|
390
|
+
does not have, so the probe could not be evaluated`. Pravda, a nic, co může čtenář udělat — přitom ve
|
|
391
|
+
**stejném běhu** a o **témže chybějícím adresáři** řekl `U-ORPHAN` příkaz (`automation-gates.md` §1
|
|
392
|
+
požadavek 4). Dvě věty pro jednu nápravu jsou druhá kolej (`change-discipline.md` § One rail per concern).
|
|
393
|
+
|
|
394
|
+
Příkaz má teď jednoho vlastníka, `workspaceRoot.js` § `describeWorkspaceFix`; `runManifest.js`
|
|
395
|
+
§ `describeMissingRoots` (d.511) i obě kontroly mostu (`D-PORT`/`D-RETIRED`/`D-LINT`) berou větu odtud.
|
|
396
|
+
Co musí checkout nést, zůstává na volajícím: řádek své kořeny deklaruje a jmenuje, kdežto most dostává
|
|
397
|
+
text od linteru, jehož kanál `skipped` nese jen `{ rule, reason }` (`api/scripts/ci/lint-biz-docs.mjs`
|
|
398
|
+
§ `markSkipped`) — parsovat tu větu by byl soukromý dialekt mezi řádkem a nástrojem, jmenovat sourozence
|
|
399
|
+
zde by z mostu udělalo druhého vlastníka konfigurace prób. Měřeno nad `git archive HEAD` do adresáře bez
|
|
400
|
+
`api_biz`; kontrolní případ: nad workspace, který `api_biz` nese, nejde žádný `D-*` řádek do NOT RUN.
|
|
401
|
+
|
|
402
|
+
### Fixed — `runPreValidation` nehlásí padlý krok pod jménem jeho operace (d.516)
|
|
403
|
+
|
|
404
|
+
`utils/preValidation.js` skládal seznam padlých kroků jako `step_id: step.step_id || step.operation`, takže
|
|
405
|
+
krok bez `step_id` dorazil ke čtenáři výsledku pod **jménem operace** — pole se jmenuje `step_id` a neslo
|
|
406
|
+
něco, co jím není, bez jakékoli stopy po záměně (`architecture-principles.md` §3). Od
|
|
407
|
+
`@onlineapps/cookbook-core` 5.0.0 je `step_id` povinné (`schemas/cookbook.v2.schema.json`
|
|
408
|
+
definitions.TaskStep.required jmenuje step_id, type, service, operation) a od d.460 orchestrátor odmítne
|
|
409
|
+
task krok, který nejmenuje operaci (`_requireStepOperation`), takže krok bez `step_id` je vadný recept —
|
|
410
|
+
a vadný recept má výsledek ukázat, ne ho přejmenovat. Kontrolní případ: krok s oběma poli hlásí své
|
|
411
|
+
vlastní `step_id` beze změny.
|
|
412
|
+
|
|
413
|
+
### Fixed — NOT RUN chybějícího sourozence nese svůj Fix (d.511)
|
|
414
|
+
|
|
415
|
+
`describeMissingRoots` (`src/manifest/runManifest.js`) hlásil, CO chybí, a nikdy CO s tím; věta s příkazem
|
|
416
|
+
se tiskla jen u čistého verdiktu (`report.js` § `describeClearOutcome`), takže běh, který zároveň něco
|
|
417
|
+
našel, Fix neukázal nikde. Příkaz je odvozen z chybějících kořenů. Měřeno nad exportem
|
|
418
|
+
`api_biz/hello-service` vedle klonu api bez `api_biz/`; v rozvržení deploy brány (`<root>/api_biz/<služba>`
|
|
419
|
+
vedle `<root>/api`) je `notRun` prázdné — U-ORPHAN i R-NODE se rozhodnou (R-NODE i bez `api_biz`, d.238).
|
|
420
|
+
|
|
421
|
+
### Added — úplnost manifestu proti šabloně v obou směrech (d.511, nález 18)
|
|
422
|
+
|
|
423
|
+
`tests/unit/templateCoverage.test.js` žádal řádek nebo třídu `own` pro každý soubor šablony; opačný směr
|
|
424
|
+
mlčel — `describeFromProblem` kontroluje tvar reference `from:`, nikdy existenci souboru, takže přejmenovaný
|
|
425
|
+
soubor šablony nechal balíček zelený a spadl až v cizím repu (`[ManifestDiscovery] Packaged file not found`).
|
|
426
|
+
Nově každá `from: { package }` jmenuje soubor, který balíček nese, a každý `files.own.allowed` má v šabloně
|
|
427
|
+
něco za sebou. Rozdíl obou množin je dnes nulový — bez baseline, bez výjimky.
|
|
428
|
+
|
|
429
|
+
### Fixed — `sharedEnv.js` neslibuje kontrolu pole `consumers`, kterou nic nedělá (d.510)
|
|
430
|
+
|
|
431
|
+
Komentář nad `renderSharedEnv` tvrdil, že kdo klíč čte, je „fakt, který kód vlastní a kontrola
|
|
432
|
+
měří". Neměří: pole `keys[].consumers` nečte žádný kód tohoto balíčku (`grep -rn consumers src/`
|
|
433
|
+
vrací jen `MockMQClient` a jednu větu komentáře) a žádná brána jinde — manifest
|
|
434
|
+
`api/config/shared-env.json` to sám říká od d.505 (`_consumers`: „NOTHING measures it").
|
|
435
|
+
Slib mechanismu, který neexistuje, je přesně vada z `doc-code-binding.md` §5: odstavec se čte
|
|
436
|
+
jako krytý, takže se nikdo nepodívá.
|
|
437
|
+
|
|
438
|
+
Komentář teď říká obě poloviny pravdivě: **měřená** je jen ta, že se `consumers` nerenderuje —
|
|
439
|
+
kontrolní případ v `tests/unit/sharedEnv.test.js` polem hne a tvrdí, že vykreslený text se
|
|
440
|
+
nehne; obsah pole drží **review**; a strojová odpověď na „kdo tento název čte" je per služba,
|
|
441
|
+
řádek `C-ENV-READS` (check `env-contract`), který porovnává názvy čtené kódem služby s jejím
|
|
442
|
+
`config/service/integration-contract.json`. Renderer se nezměnil o řádek.
|
|
443
|
+
|
|
444
|
+
### Changed — `LOG_LEVEL` v zabalené šabloně říká, kdo ho čte a kdo ne (d.510)
|
|
445
|
+
|
|
446
|
+
Klíč nese komentář „the log level an infra service's config/logging.json resolves through
|
|
447
|
+
`${LOG_LEVEL}`" — pravdivý o infrastruktuře, mlčící o biz řetězci, kde ho **nečte nikdo**:
|
|
448
|
+
v `shared/*/src` je 66 čtení `process.env` a ani jedno tohoto názvu, `@onlineapps/monitoring-core`
|
|
449
|
+
nečte prostředí vůbec (princip 1) a úroveň bere z konfigurace, kterou dostane. Čtenář biz
|
|
450
|
+
`shared.env` tak mohl klíč přenastavit a čekat účinek, který mít nemůže.
|
|
451
|
+
|
|
452
|
+
Klíč zůstává v jedné sdílené sadě — každá kopie je bajtově shodná s platformní šablonou
|
|
453
|
+
(konfirmace `biz-service-manifest` 003 §18, akceptace bod 4), takže odebrat ho jen biz nositelům
|
|
454
|
+
by znamenalo druhou sadu, tedy změnu konceptu, ne opravu věty. Opravena je věta: `why` nově
|
|
455
|
+
jmenuje infrastrukturní kolej i to, že v biz řetězci je klíč **nesen, ne čten**, a proč tam
|
|
456
|
+
přesto je. `consumers` je srovnán s měřením (přibyly `api_monitoring` a `api_meta_reader`, které
|
|
457
|
+
`LOG_LEVEL` čtou — `src/consumer/config/logging.json`, `src/config.js`).
|
|
458
|
+
|
|
459
|
+
Dopad na konzumenty: vykreslený komentář klíče se změnil, takže `oa-validate` nad biz službou,
|
|
460
|
+
která svůj `shared.env` nepřegenerovala, nahlásí `G-SHARED-ENV`. Náprava je týž jeden běh jako
|
|
461
|
+
u d.500: `npx oa-sync-template shared-env --target .`.
|
|
462
|
+
|
|
463
|
+
### Fixed — `oa-sync-template` neplánuje řádky, ze kterých nemá co renderovat (d.507)
|
|
464
|
+
|
|
465
|
+
`npx oa-sync-template --target . --check` končil v každém biz repu dvěma řádky, které nešlo
|
|
466
|
+
vyřešit: `NOT RUN G-PROD-IMAGE …` a `NOT RUN G-SETUP docs/80-setup/ - the row declares no
|
|
467
|
+
"from" reference`. Oba řádky manifestu žádnou `from:` referenci nedeklarují, protože to nejsou
|
|
468
|
+
soubory renderované z reference — `G-PROD-IMAGE` je požadavek NA obsah souboru (pin digestem),
|
|
469
|
+
`G-SETUP` požadavek na existenci adresáře; odpovídá na ně běh manifestu (`npx oa-validate`).
|
|
470
|
+
Hlášení, se kterým čtenář nemůže nic udělat, je falešná záruka (`automation-gates.md` §5) a
|
|
471
|
+
hláška bez `Fix` (§1 požadavek 4).
|
|
472
|
+
|
|
473
|
+
Množina řádků synchronizace se nově bere podle toho, co manifest už dnes rozlišuje: řádek
|
|
474
|
+
s `from:` referencí je soubor, který běh renderuje (`syncRows`), řádek bez ní se neplánuje
|
|
475
|
+
vůbec. Rozhoduje reference, ne seznam id — nový požadavkový řádek tedy nevyžaduje změnu kódu.
|
|
476
|
+
`uniformRows` zůstává celou deklarací tříd `identical`/`generated`/`contains`, takže CLI umí
|
|
477
|
+
odmítnout `docs/80-setup/` jako požadavek (se jménem řádku a během, který na něj odpovídá), ne
|
|
478
|
+
jako překlep.
|
|
479
|
+
|
|
480
|
+
`NOT RUN` zůstává pro svůj jediný případ: řádek, který běh renderovat MÁ a nedosáhne na svou
|
|
481
|
+
referenci (reference do workspace, běh mimo workspace) — nově i s `Fix: … --workspace <root>`.
|
|
482
|
+
Chování řádků s referencí se nemění (kontrolní případ v `tests/unit/uniformFilesSync.test.js`).
|
|
483
|
+
|
|
484
|
+
Dopad na konzumenty: výstup `--check` nad konformním repem je o dva řádky kratší a neobsahuje
|
|
485
|
+
žádné `NOT RUN`; `oa-sync-template docs/80-setup/ --target .` nově končí exit 2 s vysvětlením
|
|
486
|
+
místo NOT RUN.
|
|
487
|
+
|
|
488
|
+
### Changed — zabalená šablona `shared.env` nese dvě meze souborového logu (d.500)
|
|
489
|
+
|
|
490
|
+
`@onlineapps/monitoring-core` 3.0.0 vyžaduje `file.maxSize` a `file.maxFiles` bez defaultu
|
|
491
|
+
v kódu (`src/logger.js` § `REQUIRED_FILE_BOUNDS`) — služba, která je nedeklaruje, spadne při
|
|
492
|
+
konstrukci loggeru. Hodnoty rozhodl vlastník: `LOG_MAX_SIZE_BYTES=52428800`, `LOG_MAX_FILES=10`
|
|
493
|
+
(`api/docs/governance/confirmations/log-file-bounds.md` 001). Klíče přibyly do manifestu
|
|
494
|
+
`api/config/shared-env.json`, který je vlastníkem klíčové sady, a tím i do zabalené kopie
|
|
495
|
+
`templates/business-service/config/env-templates/shared.env`, kterou čte řádek `G-SHARED-ENV`.
|
|
496
|
+
|
|
497
|
+
Dopad na konzumenty: `oa-validate` nad biz službou, která klíče ve svém `shared.env` nemá,
|
|
498
|
+
nahlásí `G-SHARED-ENV`. Náprava je jeden běh: `npx oa-sync-template shared-env --target .`.
|
|
499
|
+
|
|
500
|
+
### Added — `resolveMigrationPlan` na veřejném API balíčku (d.492)
|
|
501
|
+
|
|
502
|
+
Migrační plán (které `.sql` soubory tvoří množinu a v jakém pořadí) byl dostupný jen z vnitřní
|
|
503
|
+
cesty `@onlineapps/conn-orch-validator/src/utils/setupDatabase`. Cesta dovnitř balíčku není
|
|
504
|
+
kontrakt: každý přesun v `src/utils/` rozbije konzumenta, který na nic takového nepřistoupil.
|
|
505
|
+
Funkce je nově na `src/index.js` jako **tatáž** funkce (test `toBe` proti vnitřnímu modulu), ne
|
|
506
|
+
obal — jedna definice, jedno chování (`change-discipline.md` § One rail per concern). Množina
|
|
507
|
+
exportů se jinak nemění; kontrolní případ v `tests/unit/indexExports.test.js` porovnává celý
|
|
508
|
+
seznam klíčů se snímkem před změnou.
|
|
509
|
+
|
|
510
|
+
Biz repa mají přejít na veřejnou cestu `require('@onlineapps/conn-orch-validator')`; přechod
|
|
511
|
+
v jednotlivých repech patří jejich vláknům (vnitřní cestou dnes importují
|
|
512
|
+
`api_biz/converter/tests/integration/integrationEnv.js` a tři soubory v `api_biz/emailer/tests/`).
|
|
513
|
+
|
|
514
|
+
### Fixed — brána test-coverage hlásila PASS nad prázdnou množinou testů (d.486, nález d.205)
|
|
515
|
+
|
|
516
|
+
Prázdný match je jestí exit 0 bez výstupu a každé porovnání brány iteruje množinu, takže nad
|
|
517
|
+
prázdnou nenašlo protipříklad („0 file(s) matched, 0 run by the test:all chain"). Totéž o krok
|
|
518
|
+
níž — krok řetězu `test:all` mířící do prázdného adresáře. Obojí je nález `TEST_SET_EMPTY` se
|
|
519
|
+
jménem skriptu i vzoru; hlásí se jen tam, kde je kořenem (prázdné T a `TEST_NOT_MATCHED` umlčují
|
|
520
|
+
kontrolu jednotlivých kroků). `TEST_COVERAGE_SCOPE` nové měření jmenuje.
|
|
521
|
+
|
|
522
|
+
### Fixed — R6 odmítá `^`/`~`/`latest` v každé `@onlineapps/*` závislosti, i biz-only (d.485)
|
|
523
|
+
|
|
524
|
+
Kontrola exaktnosti pinu (`libCompat.js`) seděla uvnitř větve `gated`, takže balíček, který
|
|
525
|
+
žádná infra služba neinstaluje, mohl plavat pod zelenou branou (W413). Zúžení podle
|
|
526
|
+
`infraConsumed` dál rozhoduje jen o tom, co se porovnává s infra verzí; exaktní pin platí pro
|
|
527
|
+
každou `@onlineapps/*` závislost bez výjimky (`architecture-principles.md` § Version pinning).
|
|
528
|
+
Hláška je pro gated i biz-only jedna a nese `Fix: npm install <pkg>@<verze> --save-exact`;
|
|
529
|
+
kontrola existence v SSOT předchází kontrole exaktnosti, aby `Fix:` mohl verzi jmenovat.
|
|
530
|
+
|
|
531
|
+
### Added — pravidlo `S010`: invertované tvrzení v bats netvrdí nic (d.482)
|
|
532
|
+
|
|
533
|
+
`lintScripts` čte nově i **kódové** řádky testů a hlásí příkaz s invertovaným návratovým kódem
|
|
534
|
+
ve dvou tvarech, které bats nese: `! cmd` samostatně a `cmd || ! cmd`. Změřeno na bats 1.13.0:
|
|
535
|
+
takový příkaz je vyjmut z `errexit`, takže pod `set -e` **nezpůsobí pád testu**, pokud zrovna
|
|
536
|
+
není posledním příkazem těla — řádek vypadá jako tvrzení a tvrzením je jen náhodou polohy, kterou
|
|
537
|
+
libovolný vložený řádek pod ním tiše zruší. Pravidlo proto hlásí **každý** výskyt a nerozlišuje
|
|
538
|
+
poslední příkaz. Oprava je podmíněný tvar, který návratový kód spotřebuje záměrně a řekne, co našel
|
|
539
|
+
(`if <co nesmí platit>; then echo "[ctx] problem - found: …" >&2; return 1; fi`); `if ! cmd; then … fi`
|
|
540
|
+
je právě ta oprava, ne vada, a nehlásí se. Brána přistává nad již čistým rozsahem — 0 nálezů
|
|
541
|
+
ve 146 souborech, 32 výskytů platformy přepsáno předem — bez baseline a bez skip flagu
|
|
542
|
+
(`automation-gates.md` §3). Norma: `api/docs/standards/SCRIPTS-STANDARD.md` § Enforcement.
|
|
543
|
+
|
|
544
|
+
### Changed — rozsah citací je `tests/**`, ne jen `tests/scripts/` (d.482)
|
|
545
|
+
|
|
546
|
+
`CITATION_SCOPE` je nově `tests` (rekurzivně; přípony `.bats`/`.bash`/`.sh` beze změny), a platí pro
|
|
547
|
+
`S009` i `S010`. Adresář, ve kterém se `S009` narodilo, není jediný, který testy drží: mimo něj leží
|
|
548
|
+
12 shellových souborů (`tests/scripts-docker`, `tests/e2e/helpers`, `tests/fixtures/…`). Pravidlo, které
|
|
549
|
+
čte jeden adresář a sousední ne, má díru, kterou nikdo nevidí — běh ohlásí `0 finding(s)` a nikdy neřekne,
|
|
550
|
+
které soubory neotevřel (`automation-gates.md` §5). Rozsah byl před rozsířením změřen čistý pro obě
|
|
551
|
+
pravidla, takže ani zde není baseline. Jméno konstanty se nemění — exportuje ji CLI do svých hlášek.
|
|
552
|
+
|
|
7
553
|
## [9.0.0] — 2026-09-15
|
|
8
554
|
|
|
9
555
|
### Removed — šablona už nenese job `verify-installation-contract` (d.470)
|