@onlineapps/conn-orch-validator 6.0.0 → 6.0.1

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/README.md CHANGED
@@ -9,11 +9,16 @@ Coordinates validation across ALL layers (base, infra, orch, business) to ensure
9
9
  This is **NOT** a development testing tool. This is a **production validation orchestrator** that:
10
10
 
11
11
  1. **Validates service structure** - directories, files, configuration
12
- 2. **Validates configuration** - config.json, operations.json compliance
13
- 3. **Validates business logic** - cookbook tests with mocked infrastructure
14
- 4. **Validates HTTP API** - endpoints respond correctly
15
- 5. **Validates connector integration** - all connectors work with service
16
- 6. **Generates validation proof** - cryptographic SHA256 proof for registry
12
+ 2. **Validates configuration** - `config.json`, `operations.json` compliance
13
+ 3. **Validates the environment contract** - every `env.required` name is set
14
+ 4. **Validates operations** - the v3 handler-registry rules
15
+ 5. **Validates business logic** - cookbook tests with mocked infrastructure
16
+ 6. **Validates connector integration** - the two declarations agree and the environment backs them
17
+ 7. **Generates validation proof** - SHA256 proof carried into registration
18
+
19
+ There is no HTTP step. Biz containers expose no HTTP surface (ADR 0005), so
20
+ nothing here probes an endpoint — the per-operation endpoint probe and the
21
+ `/health` probe were both removed with it.
17
22
 
18
23
  Used in **Tier 1 Pre-Validation** (offline, before registration) and invoked automatically by ServiceWrapper.
19
24
 
@@ -22,18 +27,13 @@ Used in **Tier 1 Pre-Validation** (offline, before registration) and invoked aut
22
27
  **You don't use this directly!** ServiceWrapper handles validation automatically:
23
28
 
24
29
  ```javascript
25
- // services/my-service/index.js
26
- const { ServiceWrapper } = require('@onlineapps/service-wrapper');
27
-
28
- const wrapper = new ServiceWrapper({
29
- service: app,
30
- serviceRoot: __dirname
31
- });
32
-
33
- // Validation happens automatically
34
- await wrapper.initialize();
30
+ // index.js of a biz service — the whole file
31
+ require('@onlineapps/service-wrapper').bootstrap(__dirname);
35
32
  ```
36
33
 
34
+ `bootstrap()` builds the wrapper from `src/config`, and `wrapper.initialize()`
35
+ runs Tier-1 validation in phase 0.2 — before MQ connects, before registration.
36
+
37
37
  **No test files needed in business service!**
38
38
 
39
39
  ---
@@ -43,7 +43,7 @@ await wrapper.initialize();
43
43
  1. **Service Structure** - directories and files exist
44
44
  2. **Config Files** - valid JSON, required fields
45
45
  3. **Environment Contract** - every variable the contract declares `env.required` is set
46
- 4. **Operations Compliance** - follows OPERATIONS.md standard
46
+ 4. **Operations Compliance** - every operation declares `handler`, `bundle_scope`, `input`, `output`, and none carries a retired v2 field (`endpoint`, `method`, `path`); a missing `description` is a warning
47
47
  5. **Cookbook Tests** - business logic + integration (MOCKED infra)
48
48
  6. **Connector Integration** - the connector declarations agree and the environment backs them
49
49
 
@@ -116,7 +116,7 @@ services/my-service/
116
116
  "serviceName": "hello-service",
117
117
  "version": "1.0.0",
118
118
  "validator": "@onlineapps/conn-orch-validator",
119
- "validatorVersion": "2.0.6",
119
+ "validatorVersion": "<this package's version, read from its package.json>",
120
120
  "validatedAt": "2025-10-22T10:30:45.123Z",
121
121
  "testsRun": 15,
122
122
  "testsPassed": 15,
@@ -127,29 +127,68 @@ services/my-service/
127
127
  ```
128
128
 
129
129
  **Proof Lifecycle:**
130
- - **Valid for:** 7 days OR until service fingerprint changes
131
- - **Fingerprint:** SHA256 hash of (version + operations + dependencies + config)
132
- - **Revalidation:** Automatic if proof missing/invalid/expired
133
- - **Registry:** Accepts service with valid proof (skips Tier 2 validation)
130
+ - **Written:** on every successful validation, i.e. on every boot. There is no
131
+ proof cache the one that existed skipped steps 1-3 and 5-6 to save 6 ms and
132
+ bought a window of up to seven days in which validation asserted something no
133
+ longer true. It is gone, and with it the 7-day expiry it needed.
134
+ - **Fingerprint:** SHA256 over (service version + operations + `@onlineapps/*`
135
+ dependencies + config + infra files + cookbooks + seeds), stored in the proof
136
+ as `contractFingerprint`. Nothing reads it back to skip work; it records what
137
+ the run covered.
138
+ - **Registry:** the proof travels in the registration payload
139
+ (`ServiceWrapper.js`, `validationProof` field) — a service that fails
140
+ validation never reaches registration, because phase 0.2 throws.
134
141
 
135
142
  ---
136
143
 
144
+ ## Readiness scoring (`ServiceReadinessValidator`)
145
+
146
+ A separate scorer from the six-step Tier-1 run above. Tier-1 stopped calling it
147
+ in 2026-08 — its verdict was a strict function of steps 2 and 3, so it announced
148
+ a result it never independently reached. What consumes it today is
149
+ `helpers/createServiceReadinessTests`, and through it every biz repo's
150
+ `tests/bootstrap/` suite.
151
+
152
+ | Check | Weight | Required | What it means |
153
+ |---|---|---|---|
154
+ | `operations` | 80 | yes | the v3 rules — `handler`, `bundle_scope`, `input`, `output`, no retired v2 field |
155
+ | `cookbook` | 15 | no | runs only when a `testCookbook` is passed; structural validation of it |
156
+ | `registry` | 5 | no | runs only when a `registry` is passed; the service can register and its version does not clash |
157
+
158
+ `ready` is true when every required check passed AND the score is at least 60.
159
+ The retired `health` check's 20 points folded into `operations` (ADR 0005), so
160
+ the maximum is still 100.
161
+
162
+ **Every evaluation writes exactly one line** through the injected logger:
163
+ `[ServiceReadinessValidator] Readiness evaluated` with a structured object
164
+ (`serviceName`, `score`, `maxScore`, `ready`, `checks` as `{name: {passed,
165
+ score}}`, `errors`, `warnings`). A refusal adds one `error`-level line,
166
+ `[ServiceReadinessValidator] Service not ready`. There is no per-check
167
+ narration: one evaluation, one complete, machine-readable record.
168
+
169
+ The constructor requires a logger with all four of `info`, `warn`, `error`,
170
+ `debug`, and says which one is missing when it is not — see
171
+ `docs/governance/confirmations/connector-logger-contract.md`.
172
+
137
173
  ## Implementation Standard Levels
138
174
 
139
175
  The validator evaluates each service against cumulative implementation standards. Levels are ordered — each requires all previous to pass:
140
176
 
141
177
  | Level | Name | Checks | Since |
142
178
  |-------|------|--------|-------|
143
- | **v1.0** | Base Service Standard | `config/service/`, `src/app.js`, `index.js`, valid `config.json` + `operations.json`, `@onlineapps/service-wrapper` dep | 2025-06 |
179
+ | **v1.0** | Base Service Standard | `config/service/`, `src/`, `tests/`, `src/handlers/` (v3 handler modules — ADR 0005 replaced `src/app.js`), `index.js`, `config.json` with `service.name`, `operations.json` with an `operations` object, `@onlineapps/service-wrapper` dep | 2025-06 |
144
180
  | **v1.1** | Multitenancy Standard | `wrapper.tenantContext` configured in `config.json` | 2026-03 |
145
- | **v1.2** | Business Error Handling | `business_error_contract` (some file under `src/**` imports a `BusinessError` family from `@onlineapps/service-wrapper` or declares the brand `onlineapps.businessError`) + `no_retired_error_hierarchy` (no error class imported from `@onlineapps/service-common` anywhere under `src/`) | 2026-03 |
181
+ | **v1.2** | Business Error Handling Standard | `business_error_contract` (some file under `src/**` imports a `BusinessError` family from `@onlineapps/service-wrapper` or declares the brand `onlineapps.businessError`) + `no_retired_error_hierarchy` (no error class imported from `@onlineapps/service-common` anywhere under `src/`) | 2026-03 |
182
+ | **v1.3** | Zero-HTTP Shape (ADR 0005) | `src/app.js` absent, `src/routes/` absent, `src/middlewares/` absent, `express` not in dependencies | 2026-08 |
146
183
 
147
184
  **Key properties:**
148
185
  - **Cumulative** — v1.2 requires v1.0 + v1.1 to also pass
149
186
  - **Baked into validator** — older validator versions naturally know fewer levels (backward compatible)
150
187
  - **Warnings** — next unsatisfied level generates `STANDARD_LEVEL_GAP` warnings with specific missing checks
151
- - **Exposed in `/info`**ServiceWrapper's `GET /info` endpoint returns the highest satisfied level
152
- - **In validation results** `validate()` returns `standardLevel` and `standardDetails`
188
+ - **In validation results** — `ServiceStructureValidator.validate()` returns
189
+ `standardLevel` and `standardDetails`. That is the only place the level
190
+ surfaces: `GET /info` used to carry it and was retired with the rest of the
191
+ HTTP surface (ADR 0005), and nothing has taken its place
153
192
 
154
193
  ```javascript
155
194
  // Programmatic access
@@ -168,12 +207,7 @@ ServiceStructureValidator.getStandardLevels();
168
207
 
169
208
  ## Related Documentation
170
209
 
171
- - [SERVICE_REGISTRATION_FLOW.md](/services/hello-service/docs/SERVICE_REGISTRATION_FLOW.md)
172
210
  - [/docs/architecture/validator.md](/docs/architecture/validator.md)
173
211
  - [/docs/biz/30-operations/schema-v3.md](/docs/biz/30-operations/schema-v3.md)
174
212
  - [/docs/standards/ERROR_HANDLING.md](/docs/standards/ERROR_HANDLING.md)
175
213
  - [@onlineapps/service-validator-core](/shared/service-validator-core/README.md)
176
-
177
- ---
178
-
179
- *Last updated: 2026-03-24*
package/docs/DESIGN.md CHANGED
@@ -5,13 +5,14 @@
5
5
  Validation framework for OA Drive microservices. Drives two flows:
6
6
 
7
7
  1. **Pre-validation** (Tier 1) — runs during `service-wrapper` startup. Verifies
8
- structure (config files, package.json), readiness (endpoints respond, health
9
- works) and produces a signed `validation-proof.json` stored under
10
- `conn-runtime/`.
8
+ structure (config files, package.json), the environment contract, the v3
9
+ operations rules and the cookbook tests, then produces a signed
10
+ `validation-proof.json` stored under `conn-runtime/`. Nothing is probed over
11
+ HTTP: biz containers expose no endpoints (ADR 0005).
11
12
  2. **Readiness checks** — a reusable probe (`createServiceReadinessTests`)
12
13
  consumable from the `tests/bootstrap/` suites of individual biz services.
13
14
 
14
- The single source of truth for service endpoint metadata is
15
+ The single source of truth for service operation metadata is
15
16
  [`operations.json`](../../../docs/biz/30-operations/registration-wire.md).
16
17
  OpenAPI iteration (`paths`/`operationId`) is NOT supported — that legacy
17
18
  surface was removed together with the now-retired `ServiceValidator` /
@@ -38,8 +39,9 @@ surface was removed together with the now-retired `ServiceValidator` /
38
39
 
39
40
  ### Production Validation
40
41
 
41
- - `ValidationOrchestrator` — 5-step pre-validation pipeline (structure, config,
42
- operations, cookbooks, connectors), emits proof
42
+ - `ValidationOrchestrator` — six-step pre-validation pipeline (structure,
43
+ config, environment contract, operations, cookbooks, connectors), emits proof.
44
+ Each step announces itself as `Step N/6` through the injected logger
43
45
  - `ServiceReadinessValidator` — score-based checks (operations 80 / cookbook 15
44
46
  / registry 5). Not used by the orchestrator: its only consumer is
45
47
  `createServiceReadinessTests`, and through it the biz repos'
@@ -52,27 +54,31 @@ surface was removed together with the now-retired `ServiceValidator` /
52
54
 
53
55
  ### Test Suite Helpers
54
56
 
55
- - `createServiceReadinessTests(options)` — Jest suite generator
57
+ - `createServiceReadinessTests(testsDir, options)` — Jest suite generator
56
58
 
57
59
  ## Integration Points
58
60
 
59
61
  - `@onlineapps/service-wrapper` instantiates `ValidationOrchestrator` during
60
- wrapper startup. Proof is cached under `conn-runtime/validation-proof.json`
61
- (30-day validity, invalidated by config fingerprint change includes
62
- operations map, see
63
- [operations-registry-contract.md §3](../../../docs/biz/30-operations/registration-wire.md)).
64
- - The biz repos import `createServiceReadinessTests` from this package in their
65
- `tests/bootstrap/service-readiness.test.js` (`converter`, `ingest`,
66
- `hello-service`).
62
+ wrapper startup, in phase 0.2. **There is no proof cache**: the full
63
+ validation runs on every boot, and `conn-runtime/validation-proof.json` is its
64
+ output, not its shortcut. The cache that once lived here skipped most steps to
65
+ save milliseconds and bought a window in which validation asserted something
66
+ no longer true; the fingerprint it keyed on covered less than it claimed. The
67
+ proof travels into registration (see
68
+ [registration-wire.md](../../../docs/biz/30-operations/registration-wire.md)).
69
+ - Biz repos import `createServiceReadinessTests` from this package in their
70
+ `tests/bootstrap/service-readiness.test.js`. Which repos do so changes with
71
+ the service headcount, so grep for the symbol rather than trusting a list
72
+ written here.
67
73
  - Pre-validation is driven by the `oa-biz-ci-gate run-prevalidation` subcommand,
68
74
  not by a Jest suite generator.
69
75
 
70
76
  ## What We Test
71
77
 
72
- 1. **Service contract** — operations.json structure + endpoint reachability
73
- 2. **Workflow capability** — can process cookbooks
74
- 3. **Infrastructure** — registry / MQ / storage connectivity
75
- 4. **Health** — `/health` returns 200
78
+ 1. **Service contract** — structure, config files and the v3 operations rules
79
+ 2. **Environment contract** — every name declared `env.required` is set
80
+ 3. **Workflow capability** — can process cookbooks, in-process, with mocks
81
+ 4. **Connector contract** — the two declarations agree and the environment backs them
76
82
 
77
83
  ## What We DO NOT Test
78
84
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onlineapps/conn-orch-validator",
3
- "version": "6.0.0",
3
+ "version": "6.0.1",
4
4
  "description": "Validation orchestrator for OA Drive microservices - coordinates validation across all layers (base, infra, orch, business)",
5
5
  "main": "src/index.js",
6
6
  "bin": {
@@ -15,43 +15,53 @@ Instead of **copying test code** between services, we provide **reusable test he
15
15
 
16
16
  ### createServiceReadinessTests
17
17
 
18
- **Purpose:** Integration test for service HTTP API readiness
18
+ **Purpose:** a jest suite proving a service is ready — its shape on disk and its
19
+ v3 operations contract. Nothing is started and nothing is called over the
20
+ network: biz containers run zero HTTP (ADR 0005), so there is no port to bind,
21
+ no endpoint to probe and no `/health` to check.
19
22
 
20
23
  **File:** `createServiceReadinessTests.js`
21
24
 
22
25
  **What it does:**
23
- - Validates service structure (config/service/, src/handlers/, package.json)
24
- - Validates configuration files (config.json, operations.json)
25
- - Tests all operations endpoints
26
- - Validates health endpoint
27
- - Auto-generates cookbook tests (with mocks)
28
- - Tests registry compatibility (with mocks)
29
- - Scores 100/100 with all checks
26
+ - Validates service structure (config/service/, src/, tests/, src/handlers/, package.json) and THROWS before any test runs if it fails
27
+ - Loads `config/service/config.json` and `config/service/operations.json` — the only configuration path
28
+ - Scores readiness through `ServiceReadinessValidator` (operations, plus cookbook and registry when the optional checks are on)
29
+ - Synthesises a cookbook from the declared operations, with mock input generated from each `input` schema
30
+ - Uses `MockRegistry` for the registry check — nothing real is contacted
31
+ - Asserts every operation declares `handler` (matching `handlers/<path>#<export>`) and a valid `bundle_scope`, and carries no retired v2 `endpoint` / `method`
30
32
 
31
33
  **Usage:**
32
34
  ```javascript
33
- // services/my-service/tests/integration/service-readiness.test.js
35
+ // <service>/tests/bootstrap/service-readiness.test.js
34
36
  const { createServiceReadinessTests } = require('@onlineapps/conn-orch-validator');
35
37
 
36
38
  createServiceReadinessTests(__dirname);
37
39
  ```
38
40
 
41
+ The service root is resolved two levels up from the directory you pass, so the
42
+ file belongs in `tests/<something>/`.
43
+
39
44
  **Options:**
40
45
  ```javascript
41
46
  createServiceReadinessTests(__dirname, {
42
- testPort: 5556, // Test server port (default: 5556)
43
47
  includeOptionalChecks: true, // Cookbook & registry checks (default: true)
44
- timeout: 15000 // Test timeout in ms (default: 15000)
48
+ timeout: 15000, // Test timeout in ms (default: 15000)
49
+ logger: myLogger // Logger for ServiceReadinessValidator (default: console)
45
50
  });
46
51
  ```
47
52
 
48
- **Score Breakdown:**
49
- - operations: 30 points (required)
50
- - endpoints: 30 points (required)
51
- - health: 20 points (required)
52
- - cookbook: 15 points (optional, with mocks)
53
- - registry: 5 points (optional, with mocks)
54
- - **Total: 100/100**
53
+ `logger` defaults to `console` on purpose — in a bootstrap suite stdout is the
54
+ report the developer reads. See
55
+ [FALLBACKS_INVENTORY.md](/docs/standards/FALLBACKS_INVENTORY.md) §5.6.
56
+
57
+ **Score Breakdown** (owned by `ServiceReadinessValidator`):
58
+ - operations: 80 points (required)
59
+ - cookbook: 15 points (optional, structural validation of the synthesised cookbook)
60
+ - registry: 5 points (optional, MockRegistry)
61
+ - **Total: 100/100** — ready requires every required check to pass and a score of at least 60
62
+
63
+ With `includeOptionalChecks` on, the suite asserts the full 100; with it off, it
64
+ asserts at least 80 and a passing `operations` check.
55
65
 
56
66
  ---
57
67
 
@@ -70,12 +80,12 @@ The helper uses `ServiceStructureValidator` to validate service structure BEFORE
70
80
 
71
81
  ✅ ALL CHECKS PASSED
72
82
 
73
- ✓ Found Configuration directory: config/service
83
+ ✓ Found Configuration directory
74
84
  ✓ Found Source code directory: src
75
85
  ✓ Found Tests directory: tests
76
86
  ✓ Found valid config.json
77
87
  ✓ Found valid operations.json
78
- ✓ Found src/app.js
88
+ ✓ Found src/handlers/
79
89
  ✓ Found 3 cookbook test(s)
80
90
 
81
91
  ═══════════════════════════════════════════════════════════════
@@ -107,20 +117,21 @@ If validation fails, clear error messages are shown:
107
117
  The helper automatically detects and loads:
108
118
 
109
119
  ```javascript
110
- // Service root (2 levels up from tests/integration/)
111
- const serviceRoot = path.resolve(__dirname, '../..');
120
+ // Service root (2 levels up from the directory you passed)
121
+ const serviceRoot = path.resolve(testsDir, '../..');
112
122
 
113
- // Standard file locations
114
- const config = require(path.join(serviceRoot, 'config/service/config.json'));
115
- const operations = require(path.join(serviceRoot, 'config/service/operations.json'));
116
- const app = require(path.join(serviceRoot, 'src/app.js'));
123
+ // The only configuration path — the legacy conn-config/ layout is gone
124
+ const config = JSON.parse(fs.readFileSync(path.join(serviceRoot, 'config/service/config.json'), 'utf-8'));
125
+ const operations = JSON.parse(fs.readFileSync(path.join(serviceRoot, 'config/service/operations.json'), 'utf-8'));
117
126
 
118
127
  // Extract metadata
119
128
  const serviceName = config.service.name;
120
129
  const serviceVersion = config.service.version;
121
- const healthEndpoint = config.wrapper?.health?.endpoint || '/health';
122
130
  ```
123
131
 
132
+ Nothing loads `src/app.js` and nothing reads a health endpoint: both belonged to
133
+ the Express surface ADR 0005 removed.
134
+
124
135
  No service-specific code needed!
125
136
 
126
137
  ---
@@ -133,7 +144,7 @@ When creating new generic test helpers:
133
144
  2. **Accept testsDir as first parameter:** `function create...(testsDir, options)`
134
145
  3. **Calculate service root:** `const serviceRoot = path.resolve(testsDir, '../..');`
135
146
  4. **Validate structure first:** Use `ServiceStructureValidator`
136
- 5. **Load standard files:** config.json, operations.json, app.js
147
+ 5. **Load standard files:** `config/service/config.json`, `config/service/operations.json`
137
148
  6. **Provide clear output:** Log validation results, test progress
138
149
  7. **Export single function:** `module.exports = { create...Tests };`
139
150
  8. **Update index.js:** Add to exports
@@ -176,8 +187,3 @@ module.exports = { createMyTests };
176
187
  - [/tests/TESTING.md](/tests/TESTING.md) - SPOT principles
177
188
  - [/shared/connector/conn-orch-validator/README.md](/shared/connector/conn-orch-validator/README.md) - Package documentation
178
189
  - [/shared/connector/conn-orch-validator/docs/DESIGN.md](/shared/connector/conn-orch-validator/docs/DESIGN.md) - Design principles
179
-
180
- ---
181
-
182
- *Last updated: 2025-10-21*
183
- *Maintained by: OA Drive Core Team*