xoonya 1.2.0 → 1.4.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/README.md +8 -0
- package/integrations/registry.js +171 -0
- package/package.json +1 -1
- package/server.js +29 -0
package/README.md
CHANGED
|
@@ -98,6 +98,8 @@ Primary proof-model routes:
|
|
|
98
98
|
- `GET /v1/integrations`
|
|
99
99
|
- `GET /v1/integrations/summary`
|
|
100
100
|
- `GET /v1/integrations/snapshot`
|
|
101
|
+
- `GET /v1/integrations/promotion-readiness`
|
|
102
|
+
- `GET /v1/integrations/promotion-workflow`
|
|
101
103
|
|
|
102
104
|
Preserved compatibility routes:
|
|
103
105
|
|
|
@@ -160,6 +162,8 @@ The package now includes:
|
|
|
160
162
|
- `exportIntegrationRegistrySnapshot(...)`
|
|
161
163
|
- `validateIntegrationRegistrySnapshot(...)`
|
|
162
164
|
- `summarizeIntegrationPromotionReadiness(...)`
|
|
165
|
+
- `summarizeIntegrationPromotionWorkflow(...)`
|
|
166
|
+
- `summarizeIntegrationPromotionWorkflowList(...)`
|
|
163
167
|
|
|
164
168
|
Those helpers are intended to normalize proof-adjacent integrations without letting pricing, workflow, or settlement logic leak into the proof kernel.
|
|
165
169
|
|
|
@@ -172,6 +176,9 @@ For lightweight local review flows, `xoonya` also includes a small repo-local pr
|
|
|
172
176
|
```bash
|
|
173
177
|
node scripts/registry_cli.js validate-registration --example verifier
|
|
174
178
|
node scripts/registry_cli.js export-snapshot --registration_state staging_registered
|
|
179
|
+
node scripts/registry_cli.js promotion-readiness --integration partner.verifier.lattice_notary
|
|
180
|
+
node scripts/registry_cli.js promotion-workflow --integration partner.verifier.lattice_notary
|
|
181
|
+
node scripts/registry_cli.js promotion-workflow-summary --source third_party_example --registration_state staging_registered --bundled false
|
|
175
182
|
```
|
|
176
183
|
|
|
177
184
|
That tooling is intentionally narrow: validate proof-integration registration posture and export filtered proof registry snapshots.
|
|
@@ -182,3 +189,4 @@ The proof-side readiness layer now also makes promotion posture explicit without
|
|
|
182
189
|
- default-eligible means it can participate in the proof-side default posture
|
|
183
190
|
- production-default-ready means certification, maturity, bundled posture, and selection posture all line up
|
|
184
191
|
- blockers are returned as data instead of being left implicit
|
|
192
|
+
- promotion workflow summaries now show the next proof-side transition and the current recommendation without introducing approval state
|
package/integrations/registry.js
CHANGED
|
@@ -10,6 +10,13 @@ function sortStrings(values) {
|
|
|
10
10
|
return Array.from(new Set((Array.isArray(values) ? values : []).filter(Boolean))).sort();
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
+
function summarizeCounts(values, fieldName) {
|
|
14
|
+
return sortStrings(values).map((value) => ({
|
|
15
|
+
[fieldName]: value,
|
|
16
|
+
count: values.filter((entry) => entry === value).length
|
|
17
|
+
}));
|
|
18
|
+
}
|
|
19
|
+
|
|
13
20
|
function createIntegrationDescriptor(descriptor, extras = {}) {
|
|
14
21
|
return {
|
|
15
22
|
integration_id: descriptor.integration_id,
|
|
@@ -190,6 +197,129 @@ function buildProofPromotionReadinessSummary(input = {}) {
|
|
|
190
197
|
};
|
|
191
198
|
}
|
|
192
199
|
|
|
200
|
+
function summarizeProofPromotionBlockerCategories(blockers = []) {
|
|
201
|
+
const values = Array.isArray(blockers) ? blockers : [];
|
|
202
|
+
const categories = [];
|
|
203
|
+
if (values.some((entry) => entry === "registration_state_missing")) categories.push("registration");
|
|
204
|
+
if (values.some((entry) => entry === "certification_state_missing" || entry === "not_certified")) categories.push("certification");
|
|
205
|
+
if (values.some((entry) => entry === "integration_maturity_missing" || entry === "not_marked_production_default")) categories.push("maturity");
|
|
206
|
+
if (values.some((entry) => entry === "default_selection_disabled" || entry === "still_requires_explicit_selection")) categories.push("selection");
|
|
207
|
+
if (values.some((entry) => entry === "not_bundled_for_default_rollout")) categories.push("rollout");
|
|
208
|
+
return summarizeCounts(categories, "category");
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
function buildProofCertificationGapSummary(readiness = {}, integration = {}) {
|
|
212
|
+
const blockers = Array.isArray(readiness.blockers) ? readiness.blockers : [];
|
|
213
|
+
const certificationScope = Array.isArray(integration.certification_scope) ? integration.certification_scope.filter(Boolean) : [];
|
|
214
|
+
const verifiedWith = integration.registration && Array.isArray(integration.registration.verified_with)
|
|
215
|
+
? integration.registration.verified_with.filter(Boolean)
|
|
216
|
+
: [];
|
|
217
|
+
const missingRequirements = [];
|
|
218
|
+
const productionReady = readiness.production_default_ready === true;
|
|
219
|
+
|
|
220
|
+
if (blockers.includes("certification_state_missing") || blockers.includes("not_certified")) {
|
|
221
|
+
missingRequirements.push("certification_state");
|
|
222
|
+
}
|
|
223
|
+
if (!productionReady && certificationScope.length < 1) {
|
|
224
|
+
missingRequirements.push("certification_scope");
|
|
225
|
+
}
|
|
226
|
+
if (!productionReady && verifiedWith.length < 1) {
|
|
227
|
+
missingRequirements.push("verified_with");
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
return {
|
|
231
|
+
certification_state: readiness.certification_state || null,
|
|
232
|
+
certification_scope_count: certificationScope.length,
|
|
233
|
+
verified_with_count: verifiedWith.length,
|
|
234
|
+
missing_requirements: missingRequirements,
|
|
235
|
+
certifiable: missingRequirements.length === 0
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
function buildProofNextTransitionSummary(readiness = {}) {
|
|
240
|
+
const blockers = Array.isArray(readiness.blockers) ? readiness.blockers : [];
|
|
241
|
+
if (readiness.production_default_ready === true) {
|
|
242
|
+
return {
|
|
243
|
+
action: "maintain_production_default",
|
|
244
|
+
reason: "integration already satisfies proof-side production-default posture",
|
|
245
|
+
requirements: [],
|
|
246
|
+
later_actions: []
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
if (blockers.includes("registration_state_missing")) {
|
|
250
|
+
return {
|
|
251
|
+
action: "register_integration",
|
|
252
|
+
reason: "proof integration is missing a registration state",
|
|
253
|
+
requirements: ["registration_state"],
|
|
254
|
+
later_actions: ["complete_certification", "promote_maturity", "enable_default_selection", "bundle_for_default_rollout"]
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
if (blockers.includes("not_certified") || blockers.includes("certification_state_missing")) {
|
|
258
|
+
return {
|
|
259
|
+
action: "complete_certification",
|
|
260
|
+
reason: "proof integration is not yet certified",
|
|
261
|
+
requirements: ["certification_state"],
|
|
262
|
+
later_actions: ["promote_maturity", "enable_default_selection", "bundle_for_default_rollout"]
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
if (blockers.includes("not_marked_production_default") || blockers.includes("integration_maturity_missing")) {
|
|
266
|
+
return {
|
|
267
|
+
action: "promote_maturity",
|
|
268
|
+
reason: "proof integration maturity is not yet aligned with production-default posture",
|
|
269
|
+
requirements: ["integration_maturity"],
|
|
270
|
+
later_actions: ["enable_default_selection", "bundle_for_default_rollout"]
|
|
271
|
+
};
|
|
272
|
+
}
|
|
273
|
+
if (blockers.includes("default_selection_disabled") || blockers.includes("still_requires_explicit_selection")) {
|
|
274
|
+
return {
|
|
275
|
+
action: "enable_default_selection",
|
|
276
|
+
reason: "proof integration remains explicit-selection only",
|
|
277
|
+
requirements: ["default_selection_enabled", "requires_explicit_selection=false"],
|
|
278
|
+
later_actions: blockers.includes("not_bundled_for_default_rollout") ? ["bundle_for_default_rollout"] : []
|
|
279
|
+
};
|
|
280
|
+
}
|
|
281
|
+
if (blockers.includes("not_bundled_for_default_rollout")) {
|
|
282
|
+
return {
|
|
283
|
+
action: "bundle_for_default_rollout",
|
|
284
|
+
reason: "proof integration is not yet bundled for production-default rollout",
|
|
285
|
+
requirements: ["bundled=true"],
|
|
286
|
+
later_actions: []
|
|
287
|
+
};
|
|
288
|
+
}
|
|
289
|
+
return {
|
|
290
|
+
action: "review_manually",
|
|
291
|
+
reason: "proof integration posture needs review",
|
|
292
|
+
requirements: [],
|
|
293
|
+
later_actions: []
|
|
294
|
+
};
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
function buildProofPromotionRecommendationSummary(readiness = {}) {
|
|
298
|
+
const nextTransition = buildProofNextTransitionSummary(readiness);
|
|
299
|
+
if (readiness.production_default_ready === true) {
|
|
300
|
+
return {
|
|
301
|
+
recommendation: "eligible_for_production_default",
|
|
302
|
+
rationale: "proof integration is ready for production-default posture"
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
if (readiness.review_ready === true && readiness.default_eligible === false) {
|
|
306
|
+
return {
|
|
307
|
+
recommendation: "keep_staged_until_requirements_clear",
|
|
308
|
+
rationale: nextTransition.reason
|
|
309
|
+
};
|
|
310
|
+
}
|
|
311
|
+
if (readiness.review_ready === true) {
|
|
312
|
+
return {
|
|
313
|
+
recommendation: "review_for_promotion",
|
|
314
|
+
rationale: nextTransition.reason
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
return {
|
|
318
|
+
recommendation: "complete_prerequisites_first",
|
|
319
|
+
rationale: nextTransition.reason
|
|
320
|
+
};
|
|
321
|
+
}
|
|
322
|
+
|
|
193
323
|
function summarizeIntegrationPromotionReadiness(integrationOrId) {
|
|
194
324
|
const integration = typeof integrationOrId === "string"
|
|
195
325
|
? getIntegration(integrationOrId)
|
|
@@ -217,6 +347,45 @@ function summarizeIntegrationPromotionReadiness(integrationOrId) {
|
|
|
217
347
|
};
|
|
218
348
|
}
|
|
219
349
|
|
|
350
|
+
function summarizeIntegrationPromotionWorkflow(integrationOrId) {
|
|
351
|
+
const summary = summarizeIntegrationPromotionReadiness(integrationOrId);
|
|
352
|
+
if (!summary.ok) {
|
|
353
|
+
return summary;
|
|
354
|
+
}
|
|
355
|
+
const readiness = clone(summary.promotion_readiness || {});
|
|
356
|
+
return {
|
|
357
|
+
...summary,
|
|
358
|
+
certification_gaps: buildProofCertificationGapSummary(readiness, summary),
|
|
359
|
+
blocker_categories: summarizeProofPromotionBlockerCategories(readiness.blockers),
|
|
360
|
+
next_transition: buildProofNextTransitionSummary(readiness),
|
|
361
|
+
promotion_recommendation: buildProofPromotionRecommendationSummary(readiness)
|
|
362
|
+
};
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
function summarizeIntegrationPromotionWorkflowList(filters = {}) {
|
|
366
|
+
const integrations = listIntegrations(filters).map((integration) => summarizeIntegrationPromotionWorkflow(integration));
|
|
367
|
+
return {
|
|
368
|
+
ok: true,
|
|
369
|
+
integration_count: integrations.length,
|
|
370
|
+
review_ready_count: integrations.filter((entry) => entry.promotion_readiness.review_ready).length,
|
|
371
|
+
production_default_ready_count: integrations.filter((entry) => entry.promotion_readiness.production_default_ready).length,
|
|
372
|
+
certifiable_count: integrations.filter((entry) => entry.certification_gaps.certifiable).length,
|
|
373
|
+
next_actions: summarizeCounts(
|
|
374
|
+
integrations.map((entry) => entry.next_transition.action).filter(Boolean),
|
|
375
|
+
"action"
|
|
376
|
+
),
|
|
377
|
+
recommendations: summarizeCounts(
|
|
378
|
+
integrations.map((entry) => entry.promotion_recommendation.recommendation).filter(Boolean),
|
|
379
|
+
"recommendation"
|
|
380
|
+
),
|
|
381
|
+
blocker_categories: summarizeCounts(
|
|
382
|
+
integrations.flatMap((entry) => (entry.blocker_categories || []).map((item) => item.category)).filter(Boolean),
|
|
383
|
+
"category"
|
|
384
|
+
),
|
|
385
|
+
integrations
|
|
386
|
+
};
|
|
387
|
+
}
|
|
388
|
+
|
|
220
389
|
const BUILTIN_INTEGRATIONS = [
|
|
221
390
|
createIntegrationDescriptor({
|
|
222
391
|
integration_id: "builtin.identity.legacy_material",
|
|
@@ -454,6 +623,8 @@ module.exports = {
|
|
|
454
623
|
listIntegrations,
|
|
455
624
|
summarizeIntegrations,
|
|
456
625
|
summarizeIntegrationPromotionReadiness,
|
|
626
|
+
summarizeIntegrationPromotionWorkflow,
|
|
627
|
+
summarizeIntegrationPromotionWorkflowList,
|
|
457
628
|
validateIntegrationRegistration,
|
|
458
629
|
importRegisteredIntegration,
|
|
459
630
|
createIntegrationRegistrySnapshot,
|
package/package.json
CHANGED
package/server.js
CHANGED
|
@@ -4,6 +4,8 @@ const proofSdk = require('./index.js');
|
|
|
4
4
|
const {
|
|
5
5
|
getIntegration,
|
|
6
6
|
exportIntegrationRegistrySnapshot,
|
|
7
|
+
summarizeIntegrationPromotionWorkflow,
|
|
8
|
+
summarizeIntegrationPromotionWorkflowList,
|
|
7
9
|
summarizeIntegrationPromotionReadiness,
|
|
8
10
|
summarizeIntegrations
|
|
9
11
|
} = require('./integrations/registry');
|
|
@@ -157,6 +159,22 @@ async function routeRequest(req, res) {
|
|
|
157
159
|
return;
|
|
158
160
|
}
|
|
159
161
|
|
|
162
|
+
if (req.method === 'GET' && url.pathname === '/v1/integrations/promotion-workflow') {
|
|
163
|
+
const response = buildIntegrationListResponse(summarizeIntegrationPromotionWorkflowList({
|
|
164
|
+
integration_class: url.searchParams.get('class'),
|
|
165
|
+
capability: url.searchParams.get('capability'),
|
|
166
|
+
surface: url.searchParams.get('surface'),
|
|
167
|
+
source: url.searchParams.get('source'),
|
|
168
|
+
certification_state: url.searchParams.get('certification_state'),
|
|
169
|
+
integration_maturity: url.searchParams.get('integration_maturity'),
|
|
170
|
+
registration_state: url.searchParams.get('registration_state'),
|
|
171
|
+
proof_scope: url.searchParams.get('proof_scope'),
|
|
172
|
+
bundled: url.searchParams.get('bundled')
|
|
173
|
+
}));
|
|
174
|
+
sendJson(res, response.status, response.payload);
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
|
|
160
178
|
if (req.method === 'GET' && url.pathname.startsWith('/v1/integrations/') && url.pathname.endsWith('/promotion-readiness')) {
|
|
161
179
|
const integrationId = decodeURIComponent(
|
|
162
180
|
url.pathname
|
|
@@ -168,6 +186,17 @@ async function routeRequest(req, res) {
|
|
|
168
186
|
return;
|
|
169
187
|
}
|
|
170
188
|
|
|
189
|
+
if (req.method === 'GET' && url.pathname.startsWith('/v1/integrations/') && url.pathname.endsWith('/promotion-workflow')) {
|
|
190
|
+
const integrationId = decodeURIComponent(
|
|
191
|
+
url.pathname
|
|
192
|
+
.slice('/v1/integrations/'.length, -'/promotion-workflow'.length)
|
|
193
|
+
.replace(/\/$/, '')
|
|
194
|
+
);
|
|
195
|
+
const response = buildIntegrationListResponse(summarizeIntegrationPromotionWorkflow(integrationId));
|
|
196
|
+
sendJson(res, response.status || 200, response.payload || response);
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
|
|
171
200
|
if (req.method === 'GET' && url.pathname.startsWith('/v1/integrations/')) {
|
|
172
201
|
const integrationId = decodeURIComponent(url.pathname.slice('/v1/integrations/'.length));
|
|
173
202
|
const response = buildIntegrationDetailResponse(getIntegration(integrationId));
|