@ai-sdlc/orchestrator 0.9.0 → 0.13.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/dist/__test-helpers/git-env.d.ts +40 -0
- package/dist/__test-helpers/git-env.js +73 -0
- package/dist/adapters.d.ts +42 -3
- package/dist/adapters.js +133 -3
- package/dist/admission-composite.d.ts +134 -1
- package/dist/admission-composite.js +170 -6
- package/dist/admission-enrichment.d.ts +12 -3
- package/dist/admission-enrichment.js +71 -10
- package/dist/admission-hc.d.ts +20 -1
- package/dist/admission-hc.js +12 -1
- package/dist/admission-score.d.ts +44 -0
- package/dist/admission-score.js +11 -2
- package/dist/backlog-adapter.d.ts +45 -0
- package/dist/backlog-adapter.js +145 -1
- package/dist/calibration.d.ts +81 -0
- package/dist/calibration.js +76 -0
- package/dist/cli/commands/git-remote.d.ts +25 -0
- package/dist/cli/commands/git-remote.js +80 -1
- package/dist/cli/commands/init-features.d.ts +507 -0
- package/dist/cli/commands/init-features.js +1100 -0
- package/dist/cli/commands/init-templates.d.ts +301 -0
- package/dist/cli/commands/init-templates.js +1341 -0
- package/dist/cli/commands/init.d.ts +67 -0
- package/dist/cli/commands/init.js +301 -2
- package/dist/cli/commands/run.js +9 -1
- package/dist/cli/index.d.ts +11 -0
- package/dist/cli/index.js +42 -8
- package/dist/compliance/composer.d.ts +79 -0
- package/dist/compliance/composer.js +258 -0
- package/dist/compliance/errors.d.ts +64 -0
- package/dist/compliance/errors.js +85 -0
- package/dist/compliance/loader.d.ts +52 -0
- package/dist/compliance/loader.js +124 -0
- package/dist/compliance/types.d.ts +184 -0
- package/dist/compliance/types.js +41 -0
- package/dist/compliance-clearance.d.ts +269 -0
- package/dist/compliance-clearance.js +269 -0
- package/dist/config.js +17 -0
- package/dist/cost-tracker.d.ts +22 -0
- package/dist/cost-tracker.js +41 -0
- package/dist/database/adapters/external.js +5 -1
- package/dist/design-authority.d.ts +13 -0
- package/dist/design-authority.js +13 -0
- package/dist/embedding/adapters/openai-text-embedding-3-small.d.ts +71 -0
- package/dist/embedding/adapters/openai-text-embedding-3-small.js +190 -0
- package/dist/embedding/consumers/tessellation-drift.d.ts +74 -0
- package/dist/embedding/consumers/tessellation-drift.js +76 -0
- package/dist/embedding/cross-provider.d.ts +78 -0
- package/dist/embedding/cross-provider.js +75 -0
- package/dist/embedding/deprecation.d.ts +151 -0
- package/dist/embedding/deprecation.js +229 -0
- package/dist/embedding/errors.d.ts +90 -0
- package/dist/embedding/errors.js +150 -0
- package/dist/embedding/index.d.ts +29 -0
- package/dist/embedding/index.js +24 -0
- package/dist/embedding/pipeline-load.d.ts +146 -0
- package/dist/embedding/pipeline-load.js +178 -0
- package/dist/embedding/registry.d.ts +45 -0
- package/dist/embedding/registry.js +61 -0
- package/dist/embedding/stale-vector.d.ts +110 -0
- package/dist/embedding/stale-vector.js +92 -0
- package/dist/embedding/storage/index.d.ts +51 -0
- package/dist/embedding/storage/index.js +43 -0
- package/dist/embedding/storage/jsonl-backend.d.ts +150 -0
- package/dist/embedding/storage/jsonl-backend.js +332 -0
- package/dist/embedding/storage/types.d.ts +135 -0
- package/dist/embedding/storage/types.js +13 -0
- package/dist/embedding/types.d.ts +180 -0
- package/dist/embedding/types.js +10 -0
- package/dist/execute.d.ts +29 -2
- package/dist/execute.js +179 -35
- package/dist/index.d.ts +14 -2
- package/dist/index.js +19 -2
- package/dist/journey/inheritance-validator.d.ts +396 -0
- package/dist/journey/inheritance-validator.js +370 -0
- package/dist/journey/state-id-drift-rule.d.ts +137 -0
- package/dist/journey/state-id-drift-rule.js +245 -0
- package/dist/journey-sa2-router.d.ts +395 -0
- package/dist/journey-sa2-router.js +308 -0
- package/dist/models/classifier.d.ts +3 -1
- package/dist/models/classifier.js +61 -5
- package/dist/pillar-breakdown.d.ts +23 -1
- package/dist/pillar-breakdown.js +9 -0
- package/dist/runners/review-agent.js +6 -2
- package/dist/runners/runner-registry.d.ts +36 -0
- package/dist/runners/runner-registry.js +90 -0
- package/dist/runtime/attestations.d.ts +663 -11
- package/dist/runtime/attestations.js +971 -24
- package/dist/runtime/index.d.ts +1 -1
- package/dist/runtime/index.js +1 -1
- package/dist/runtime/parallelism-flag.d.ts +21 -3
- package/dist/runtime/parallelism-flag.js +27 -6
- package/dist/runtime/port-allocator.d.ts +11 -0
- package/dist/runtime/port-allocator.js +30 -0
- package/dist/sa-scoring/layer3-llm.js +6 -1
- package/dist/sa-scoring/revision-proposal-config.d.ts +178 -0
- package/dist/sa-scoring/revision-proposal-config.js +198 -0
- package/dist/sa-scoring/revision-proposal.d.ts +285 -0
- package/dist/sa-scoring/revision-proposal.js +417 -0
- package/dist/signal-ingestion/adapters/community-thread.d.ts +43 -0
- package/dist/signal-ingestion/adapters/community-thread.js +55 -0
- package/dist/signal-ingestion/adapters/in-app-feedback.d.ts +67 -0
- package/dist/signal-ingestion/adapters/in-app-feedback.js +51 -0
- package/dist/signal-ingestion/adapters/manual.d.ts +78 -0
- package/dist/signal-ingestion/adapters/manual.js +112 -0
- package/dist/signal-ingestion/adapters/support-ticket.d.ts +47 -0
- package/dist/signal-ingestion/adapters/support-ticket.js +51 -0
- package/dist/signal-ingestion/classifier.d.ts +205 -0
- package/dist/signal-ingestion/classifier.js +494 -0
- package/dist/signal-ingestion/clustering-types.d.ts +36 -0
- package/dist/signal-ingestion/clustering-types.js +14 -0
- package/dist/signal-ingestion/clustering.d.ts +200 -0
- package/dist/signal-ingestion/clustering.js +413 -0
- package/dist/signal-ingestion/config.d.ts +351 -0
- package/dist/signal-ingestion/config.js +587 -0
- package/dist/signal-ingestion/d1.d.ts +252 -0
- package/dist/signal-ingestion/d1.js +235 -0
- package/dist/signal-ingestion/errors.d.ts +73 -0
- package/dist/signal-ingestion/errors.js +108 -0
- package/dist/signal-ingestion/governance-events.d.ts +181 -0
- package/dist/signal-ingestion/governance-events.js +189 -0
- package/dist/signal-ingestion/index.d.ts +35 -0
- package/dist/signal-ingestion/index.js +53 -0
- package/dist/signal-ingestion/manual-share-metric.d.ts +93 -0
- package/dist/signal-ingestion/manual-share-metric.js +106 -0
- package/dist/signal-ingestion/registry.d.ts +40 -0
- package/dist/signal-ingestion/registry.js +137 -0
- package/dist/signal-ingestion/residency.d.ts +227 -0
- package/dist/signal-ingestion/residency.js +238 -0
- package/dist/signal-ingestion/significance.d.ts +554 -0
- package/dist/signal-ingestion/significance.js +555 -0
- package/dist/signal-ingestion/types.d.ts +191 -0
- package/dist/signal-ingestion/types.js +8 -0
- package/dist/substrate/drift-composition.d.ts +270 -0
- package/dist/substrate/drift-composition.js +306 -0
- package/dist/substrate/drift-tui-surface.d.ts +61 -0
- package/dist/substrate/drift-tui-surface.js +102 -0
- package/dist/substrate/identity-class.d.ts +176 -0
- package/dist/substrate/identity-class.js +201 -0
- package/dist/tessellation/cross-soul-provenance-rule.d.ts +133 -0
- package/dist/tessellation/cross-soul-provenance-rule.js +171 -0
- package/dist/tessellation/inter-soul-embedding-distance-rule.d.ts +61 -0
- package/dist/tessellation/inter-soul-embedding-distance-rule.js +67 -0
- package/dist/tessellation/rule-registry.d.ts +269 -0
- package/dist/tessellation/rule-registry.js +92 -0
- package/dist/tessellation/soul-slug-ast-scan-rule.d.ts +90 -0
- package/dist/tessellation/soul-slug-ast-scan-rule.js +158 -0
- package/dist/tessellation-admission.d.ts +162 -0
- package/dist/tessellation-admission.js +146 -0
- package/dist/tessellation-drift.d.ts +246 -0
- package/dist/tessellation-drift.js +250 -0
- package/dist/validate-config.js +13 -0
- package/dist/validate-issue.js +2 -2
- package/dist/variant/cardinality-activation.d.ts +126 -0
- package/dist/variant/cardinality-activation.js +101 -0
- package/dist/variant/deprecation-lifecycle.d.ts +184 -0
- package/dist/variant/deprecation-lifecycle.js +208 -0
- package/dist/variant/drift-extension.d.ts +136 -0
- package/dist/variant/drift-extension.js +164 -0
- package/dist/variant/engineering-review.d.ts +185 -0
- package/dist/variant/engineering-review.js +142 -0
- package/dist/variant/index.d.ts +32 -0
- package/dist/variant/index.js +32 -0
- package/dist/variant/inheritance-validator.d.ts +165 -0
- package/dist/variant/inheritance-validator.js +139 -0
- package/dist/variant/internal-adopter/index.d.ts +11 -0
- package/dist/variant/internal-adopter/index.js +10 -0
- package/dist/variant/internal-adopter/products.d.ts +156 -0
- package/dist/variant/internal-adopter/products.js +366 -0
- package/dist/variant-admission.d.ts +316 -0
- package/dist/variant-admission.js +247 -0
- package/package.json +11 -8
|
@@ -0,0 +1,366 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RFC-0017 Phase 4 — InternalAdopter three-product reference implementation
|
|
3
|
+
* (AISDLC-437).
|
|
4
|
+
*
|
|
5
|
+
* Ships ProductA / ProductB / ProductC as canonical fixtures that demonstrate
|
|
6
|
+
* the In-Soul Variant Pattern against real-world adopter constraints. Each
|
|
7
|
+
* product is a distinct Soul on shared substrate; each declares three variants
|
|
8
|
+
* with audience-segment / form-factor / role-based specialization.
|
|
9
|
+
*
|
|
10
|
+
* **ProductD is INTENTIONALLY OMITTED** — per RFC-0017 §11 v0.4 (2026-05-26
|
|
11
|
+
* Design Authority editorial pass), ProductD's proposed variants
|
|
12
|
+
* (`annual-test`, `repair-event`, `regulatory-audit-mode`) are temporal-context-
|
|
13
|
+
* bound operational modes activated by *when* and *why* a user is in the
|
|
14
|
+
* system. Same user, different operational moment = Journey shape (RFC-0018),
|
|
15
|
+
* not Variant shape. ProductD's validation is deferred to RFC-0018 §11 as a
|
|
16
|
+
* Variant/Journey boundary validation case for the companion RFC.
|
|
17
|
+
*
|
|
18
|
+
* Variant constraints validated by `products.test.ts`:
|
|
19
|
+
* - Every variant has ≤ 5 `designImperatives` strings (closed-enum discipline)
|
|
20
|
+
* - Every variant's `designOverrides` uses only framework-owned enum fields
|
|
21
|
+
* (`colorPaletteOverlay`, `densityProfile`, `typographyScale`,
|
|
22
|
+
* `motionProfile`, `radiusProfile` per §6.1 OQ-5 2026-05-26 revisit)
|
|
23
|
+
* - All variants of a given product share the same compliance + substrate
|
|
24
|
+
* (substrate-shared check, AC #7)
|
|
25
|
+
* - All variants pass `validateVariantDeclarations()` (no inheritance
|
|
26
|
+
* violations, no nested variants, under the soft-warn / hard-limit caps)
|
|
27
|
+
*
|
|
28
|
+
* @see spec/rfcs/RFC-0017-in-soul-variant-pattern.md §11 (practitioner validation)
|
|
29
|
+
* @see ./products.test.ts — substrate-shared + closed-enum + inheritance checks
|
|
30
|
+
* @see ./admission-spotcheck.test.ts — variant-routed vs soul-aggregate scoring
|
|
31
|
+
* @see ./deprecation-lifecycle.test.ts — end-to-end lifecycle on ProductA variant
|
|
32
|
+
*/
|
|
33
|
+
/**
|
|
34
|
+
* Canonical shared substrate for the InternalAdopter product suite.
|
|
35
|
+
* Every ProductA/B/C variant inherits this identical block — substrate
|
|
36
|
+
* sharing is enforced at the fixture level (AC #7).
|
|
37
|
+
*/
|
|
38
|
+
export const INTERNAL_ADOPTER_SUBSTRATE = {
|
|
39
|
+
complianceRegimes: ['WCAG-2.1-AA'],
|
|
40
|
+
substrateInvariants: {
|
|
41
|
+
eventBus: 'internal-adopter-kafka-v1',
|
|
42
|
+
schemaRegistry: 'internal-adopter-schema-registry-v1',
|
|
43
|
+
tenantModel: 'multi-tenant-row-isolation',
|
|
44
|
+
},
|
|
45
|
+
performanceBudgets: {
|
|
46
|
+
initialLoadMs: 2500,
|
|
47
|
+
interactionResponseMs: 100,
|
|
48
|
+
},
|
|
49
|
+
observabilityRequirements: ['otel-traces', 'structured-logs', 'rum-vitals'],
|
|
50
|
+
};
|
|
51
|
+
// ── ProductA — small-utility / enterprise / county-regional ──────────────────
|
|
52
|
+
//
|
|
53
|
+
// Validates audience-segment specialization across the v0.4 visual-token
|
|
54
|
+
// surface. The three variants serve dramatically different audience sizes
|
|
55
|
+
// + cognitive-load profiles on a shared substrate.
|
|
56
|
+
const PRODUCT_A = {
|
|
57
|
+
soulId: 'product-a',
|
|
58
|
+
description: 'Utility-operations management for water + electricity service providers. ' +
|
|
59
|
+
'Validates audience-segment specialization (small ↔ enterprise ↔ county).',
|
|
60
|
+
validationAxis: 'audience-segment specialization (RFC-0017 §11)',
|
|
61
|
+
substrate: INTERNAL_ADOPTER_SUBSTRATE,
|
|
62
|
+
soulDesignImperatives: ['compliance-first-information-architecture', 'audit-trail-visibility'],
|
|
63
|
+
variants: [
|
|
64
|
+
{
|
|
65
|
+
id: 'small-utility',
|
|
66
|
+
audienceCharacteristics: {
|
|
67
|
+
segments: ['municipal-small', 'water-district-small'],
|
|
68
|
+
sizeRange: { minStaff: 1, maxStaff: 50 },
|
|
69
|
+
},
|
|
70
|
+
designOverrides: {
|
|
71
|
+
colorPaletteOverlay: 'small-utility-warm',
|
|
72
|
+
densityProfile: 'comfortable',
|
|
73
|
+
typographyScale: 'large-print',
|
|
74
|
+
motionProfile: 'reduced',
|
|
75
|
+
radiusProfile: 'rounded',
|
|
76
|
+
},
|
|
77
|
+
designImperatives: [
|
|
78
|
+
'low-tech-fluency-tolerance',
|
|
79
|
+
'single-task-focus-per-screen',
|
|
80
|
+
'forgiving-error-recovery',
|
|
81
|
+
'minimal-jargon',
|
|
82
|
+
],
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
id: 'enterprise',
|
|
86
|
+
audienceCharacteristics: {
|
|
87
|
+
segments: ['municipal-large', 'regional-utility'],
|
|
88
|
+
sizeRange: { minStaff: 51, maxStaff: 5000 },
|
|
89
|
+
},
|
|
90
|
+
designOverrides: {
|
|
91
|
+
colorPaletteOverlay: 'enterprise-cool',
|
|
92
|
+
densityProfile: 'compact',
|
|
93
|
+
typographyScale: 'default',
|
|
94
|
+
motionProfile: 'full',
|
|
95
|
+
radiusProfile: 'default',
|
|
96
|
+
},
|
|
97
|
+
designImperatives: [
|
|
98
|
+
'bulk-operation-efficiency',
|
|
99
|
+
'multi-tab-workflow-tolerance',
|
|
100
|
+
'keyboard-first-power-user-shortcuts',
|
|
101
|
+
'dashboard-density-tolerance',
|
|
102
|
+
],
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
id: 'county-regional',
|
|
106
|
+
audienceCharacteristics: {
|
|
107
|
+
segments: ['county-government', 'regional-coordinator'],
|
|
108
|
+
sizeRange: { minStaff: 20, maxStaff: 200 },
|
|
109
|
+
},
|
|
110
|
+
designOverrides: {
|
|
111
|
+
colorPaletteOverlay: 'county-civic',
|
|
112
|
+
densityProfile: 'comfortable',
|
|
113
|
+
typographyScale: 'default',
|
|
114
|
+
motionProfile: 'reduced',
|
|
115
|
+
radiusProfile: 'sharp',
|
|
116
|
+
},
|
|
117
|
+
designImperatives: [
|
|
118
|
+
'cross-jurisdiction-reconciliation-clarity',
|
|
119
|
+
'inter-agency-handoff-explicit',
|
|
120
|
+
'official-record-defensibility',
|
|
121
|
+
],
|
|
122
|
+
},
|
|
123
|
+
],
|
|
124
|
+
};
|
|
125
|
+
// ── ProductB — field-tech-on-truck / field-tech-handheld / supervisor-tablet ─
|
|
126
|
+
//
|
|
127
|
+
// Validates density profile + form-factor specialization. Same role (field
|
|
128
|
+
// operations) at different form-factors / contexts of use — density profile
|
|
129
|
+
// + motion + radius differ sharply across the three.
|
|
130
|
+
const PRODUCT_B = {
|
|
131
|
+
soulId: 'product-b',
|
|
132
|
+
description: 'Field-operations dispatch + workflow execution for utility field crews. ' +
|
|
133
|
+
'Validates density profile + form-factor specialization.',
|
|
134
|
+
validationAxis: 'density profile + form-factor specialization (RFC-0017 §11)',
|
|
135
|
+
substrate: INTERNAL_ADOPTER_SUBSTRATE,
|
|
136
|
+
soulDesignImperatives: ['offline-first-resilience', 'one-handed-operation-where-possible'],
|
|
137
|
+
variants: [
|
|
138
|
+
{
|
|
139
|
+
id: 'field-tech-on-truck',
|
|
140
|
+
audienceCharacteristics: {
|
|
141
|
+
segments: ['field-crew-mounted', 'service-truck-operator'],
|
|
142
|
+
sizeRange: { minStaff: 1, maxStaff: 4 },
|
|
143
|
+
},
|
|
144
|
+
designOverrides: {
|
|
145
|
+
colorPaletteOverlay: 'high-contrast-outdoor',
|
|
146
|
+
densityProfile: 'spacious',
|
|
147
|
+
typographyScale: 'large-print',
|
|
148
|
+
motionProfile: 'reduced',
|
|
149
|
+
radiusProfile: 'rounded',
|
|
150
|
+
},
|
|
151
|
+
designImperatives: [
|
|
152
|
+
'glanceable-from-driving-position',
|
|
153
|
+
'glove-friendly-tap-targets',
|
|
154
|
+
'sun-glare-readable-contrast',
|
|
155
|
+
'cellular-degraded-graceful',
|
|
156
|
+
],
|
|
157
|
+
},
|
|
158
|
+
{
|
|
159
|
+
id: 'field-tech-handheld',
|
|
160
|
+
audienceCharacteristics: {
|
|
161
|
+
segments: ['field-crew-handheld', 'meter-reader'],
|
|
162
|
+
sizeRange: { minStaff: 1, maxStaff: 1 },
|
|
163
|
+
},
|
|
164
|
+
designOverrides: {
|
|
165
|
+
colorPaletteOverlay: 'high-contrast-outdoor',
|
|
166
|
+
densityProfile: 'comfortable',
|
|
167
|
+
typographyScale: 'large-print',
|
|
168
|
+
motionProfile: 'reduced',
|
|
169
|
+
radiusProfile: 'rounded',
|
|
170
|
+
},
|
|
171
|
+
designImperatives: [
|
|
172
|
+
'thumb-zone-reachability',
|
|
173
|
+
'single-hand-operation',
|
|
174
|
+
'rugged-conditions-tolerance',
|
|
175
|
+
'barcode-scan-prominent',
|
|
176
|
+
],
|
|
177
|
+
},
|
|
178
|
+
{
|
|
179
|
+
id: 'supervisor-tablet',
|
|
180
|
+
audienceCharacteristics: {
|
|
181
|
+
segments: ['field-supervisor', 'crew-dispatch-coordinator'],
|
|
182
|
+
sizeRange: { minStaff: 1, maxStaff: 10 },
|
|
183
|
+
},
|
|
184
|
+
designOverrides: {
|
|
185
|
+
colorPaletteOverlay: 'supervisor-default',
|
|
186
|
+
densityProfile: 'compact',
|
|
187
|
+
typographyScale: 'data-dense',
|
|
188
|
+
motionProfile: 'full',
|
|
189
|
+
radiusProfile: 'default',
|
|
190
|
+
},
|
|
191
|
+
designImperatives: [
|
|
192
|
+
'multi-crew-overview-at-a-glance',
|
|
193
|
+
'rapid-reassignment-workflow',
|
|
194
|
+
'cross-crew-comparative-metrics',
|
|
195
|
+
'two-handed-tablet-grip-affordance',
|
|
196
|
+
],
|
|
197
|
+
},
|
|
198
|
+
],
|
|
199
|
+
};
|
|
200
|
+
// ── ProductC — billing-clerk / customer-portal / csr-dashboard ───────────────
|
|
201
|
+
//
|
|
202
|
+
// Validates role-based audience + workflow-density specialization. Same
|
|
203
|
+
// domain (billing) but radically different roles (internal staff vs end
|
|
204
|
+
// customer vs CSR) on shared substrate.
|
|
205
|
+
const PRODUCT_C = {
|
|
206
|
+
soulId: 'product-c',
|
|
207
|
+
description: 'Billing + customer-account management spanning internal staff, end customers, ' +
|
|
208
|
+
'and customer-service representatives. Validates role-based audience + ' +
|
|
209
|
+
'workflow-density specialization.',
|
|
210
|
+
validationAxis: 'role-based audience + workflow-density specialization (RFC-0017 §11)',
|
|
211
|
+
substrate: INTERNAL_ADOPTER_SUBSTRATE,
|
|
212
|
+
soulDesignImperatives: ['financial-accuracy-first', 'data-provenance-traceable'],
|
|
213
|
+
variants: [
|
|
214
|
+
{
|
|
215
|
+
id: 'billing-clerk',
|
|
216
|
+
audienceCharacteristics: {
|
|
217
|
+
segments: ['billing-staff', 'accounts-receivable'],
|
|
218
|
+
sizeRange: { minStaff: 1, maxStaff: 20 },
|
|
219
|
+
},
|
|
220
|
+
designOverrides: {
|
|
221
|
+
colorPaletteOverlay: 'billing-staff-neutral',
|
|
222
|
+
densityProfile: 'compact',
|
|
223
|
+
typographyScale: 'data-dense',
|
|
224
|
+
motionProfile: 'reduced',
|
|
225
|
+
radiusProfile: 'sharp',
|
|
226
|
+
},
|
|
227
|
+
designImperatives: [
|
|
228
|
+
'bulk-edit-efficiency',
|
|
229
|
+
'keyboard-numpad-optimized',
|
|
230
|
+
'audit-log-always-visible',
|
|
231
|
+
'reconciliation-discrepancy-prominent',
|
|
232
|
+
],
|
|
233
|
+
},
|
|
234
|
+
{
|
|
235
|
+
id: 'customer-portal',
|
|
236
|
+
audienceCharacteristics: {
|
|
237
|
+
segments: ['end-customer', 'self-service-billpayer'],
|
|
238
|
+
sizeRange: { minStaff: 1, maxStaff: 1 },
|
|
239
|
+
},
|
|
240
|
+
designOverrides: {
|
|
241
|
+
colorPaletteOverlay: 'customer-portal-friendly',
|
|
242
|
+
densityProfile: 'spacious',
|
|
243
|
+
typographyScale: 'default',
|
|
244
|
+
motionProfile: 'full',
|
|
245
|
+
radiusProfile: 'rounded',
|
|
246
|
+
},
|
|
247
|
+
designImperatives: [
|
|
248
|
+
'plain-language-no-jargon',
|
|
249
|
+
'self-service-task-completion-clarity',
|
|
250
|
+
'mobile-first-responsive',
|
|
251
|
+
'trust-signal-prominent',
|
|
252
|
+
],
|
|
253
|
+
},
|
|
254
|
+
{
|
|
255
|
+
id: 'csr-dashboard',
|
|
256
|
+
audienceCharacteristics: {
|
|
257
|
+
segments: ['customer-service-representative', 'call-center-agent'],
|
|
258
|
+
sizeRange: { minStaff: 5, maxStaff: 500 },
|
|
259
|
+
},
|
|
260
|
+
designOverrides: {
|
|
261
|
+
colorPaletteOverlay: 'csr-action-oriented',
|
|
262
|
+
densityProfile: 'compact',
|
|
263
|
+
typographyScale: 'data-dense',
|
|
264
|
+
motionProfile: 'full',
|
|
265
|
+
radiusProfile: 'default',
|
|
266
|
+
},
|
|
267
|
+
designImperatives: [
|
|
268
|
+
'caller-context-instantly-loaded',
|
|
269
|
+
'quick-resolution-workflow',
|
|
270
|
+
'sentiment-aware-prompts',
|
|
271
|
+
'screen-pop-integration',
|
|
272
|
+
],
|
|
273
|
+
},
|
|
274
|
+
],
|
|
275
|
+
};
|
|
276
|
+
// ── Exports ──────────────────────────────────────────────────────────────────
|
|
277
|
+
/**
|
|
278
|
+
* The three InternalAdopter products — ProductA / ProductB / ProductC.
|
|
279
|
+
* ProductD is intentionally omitted per RFC-0017 §11 v0.4 (deferred to
|
|
280
|
+
* RFC-0018 §11 — temporal-context-bound modes are Journey shape, not Variant).
|
|
281
|
+
*/
|
|
282
|
+
export const INTERNAL_ADOPTER_PRODUCTS = [
|
|
283
|
+
PRODUCT_A,
|
|
284
|
+
PRODUCT_B,
|
|
285
|
+
PRODUCT_C,
|
|
286
|
+
];
|
|
287
|
+
/** Individual product accessors for direct consumption by tests / tooling. */
|
|
288
|
+
export const productA = PRODUCT_A;
|
|
289
|
+
export const productB = PRODUCT_B;
|
|
290
|
+
export const productC = PRODUCT_C;
|
|
291
|
+
/**
|
|
292
|
+
* Build a `variantsBySoul` map suitable for `VariantContext`, derived from
|
|
293
|
+
* the three product declarations. Test helper + the canonical shape callers
|
|
294
|
+
* use to wire the reference impl into the admission composite.
|
|
295
|
+
*/
|
|
296
|
+
export function buildVariantsBySoul() {
|
|
297
|
+
const out = {};
|
|
298
|
+
for (const product of INTERNAL_ADOPTER_PRODUCTS) {
|
|
299
|
+
out[product.soulId] = product.variants.map((v) => ({ ...v }));
|
|
300
|
+
}
|
|
301
|
+
return out;
|
|
302
|
+
}
|
|
303
|
+
/**
|
|
304
|
+
* Build a representative `variantScores` map for spot-check admission scoring.
|
|
305
|
+
*
|
|
306
|
+
* Score shape: each variant gets `sa1` and `sa2` numbers in [0, 1].
|
|
307
|
+
* Per-variant scores are chosen to demonstrate that **variant-routed scoring
|
|
308
|
+
* differs from soul-aggregate scoring on a representative work item** (AC #6):
|
|
309
|
+
*
|
|
310
|
+
* - The "well-aligned" variant for a given work item scores HIGH (sa1=0.92,
|
|
311
|
+
* sa2=0.88).
|
|
312
|
+
* - The "misaligned" variants score LOW (sa1=0.30-0.40, sa2=0.35-0.45).
|
|
313
|
+
*
|
|
314
|
+
* If the same work item were scored at soul-aggregate scope, the average of
|
|
315
|
+
* its variants would compress to a middling value (sa1≈0.54, sa2≈0.56) —
|
|
316
|
+
* the variant-routed score for the well-aligned variant is meaningfully
|
|
317
|
+
* different (≈ +70% on sa1, +57% on sa2). This is the failure mode RFC-0017
|
|
318
|
+
* §2 documents: soul-aggregate scoring underweights variant-specific intent.
|
|
319
|
+
*
|
|
320
|
+
* The spot-check test in `admission-spotcheck.test.ts` exercises this against
|
|
321
|
+
* a representative ProductA work item ("small-utility onboarding improvement").
|
|
322
|
+
*/
|
|
323
|
+
export function buildVariantScores() {
|
|
324
|
+
return {
|
|
325
|
+
'product-a': {
|
|
326
|
+
'small-utility': { sa1: 0.92, sa2: 0.88 },
|
|
327
|
+
enterprise: { sa1: 0.35, sa2: 0.4 },
|
|
328
|
+
'county-regional': { sa1: 0.4, sa2: 0.45 },
|
|
329
|
+
},
|
|
330
|
+
'product-b': {
|
|
331
|
+
'field-tech-on-truck': { sa1: 0.9, sa2: 0.85 },
|
|
332
|
+
'field-tech-handheld': { sa1: 0.6, sa2: 0.55 },
|
|
333
|
+
'supervisor-tablet': { sa1: 0.3, sa2: 0.35 },
|
|
334
|
+
},
|
|
335
|
+
'product-c': {
|
|
336
|
+
'billing-clerk': { sa1: 0.88, sa2: 0.82 },
|
|
337
|
+
'customer-portal': { sa1: 0.3, sa2: 0.35 },
|
|
338
|
+
'csr-dashboard': { sa1: 0.55, sa2: 0.6 },
|
|
339
|
+
},
|
|
340
|
+
};
|
|
341
|
+
}
|
|
342
|
+
/**
|
|
343
|
+
* Soul-aggregate Sα₁ / Sα₂ baseline for a given Soul, computed by averaging
|
|
344
|
+
* the per-variant scores from `buildVariantScores()`. Used by the spot-check
|
|
345
|
+
* test to demonstrate that variant-routed scoring meaningfully deviates from
|
|
346
|
+
* the soul-aggregate baseline (AC #6).
|
|
347
|
+
*
|
|
348
|
+
* The aggregation rule used here is `mean` — chosen because the failure mode
|
|
349
|
+
* documented in RFC-0017 §2 is the SMOOTHING/AVERAGING effect of soul-aggregate
|
|
350
|
+
* Sα₂ scoring across heterogeneous variants. Comparing variant-routed to mean
|
|
351
|
+
* is what shows the misallocation pattern. (The admission composite itself
|
|
352
|
+
* uses `min` per OQ-4, but that's a different question — we're showing that
|
|
353
|
+
* the per-variant view is structurally different from any soul-level aggregate.)
|
|
354
|
+
*/
|
|
355
|
+
export function computeSoulAggregateBaseline(soulId) {
|
|
356
|
+
const scores = buildVariantScores()[soulId];
|
|
357
|
+
if (!scores) {
|
|
358
|
+
throw new Error(`[internal-adopter] no variant scores for soul '${soulId}' — ` +
|
|
359
|
+
`known soulIds: ${INTERNAL_ADOPTER_PRODUCTS.map((p) => p.soulId).join(', ')}`);
|
|
360
|
+
}
|
|
361
|
+
const variants = Object.values(scores);
|
|
362
|
+
const sa1 = variants.reduce((s, v) => s + v.sa1, 0) / variants.length;
|
|
363
|
+
const sa2 = variants.reduce((s, v) => s + v.sa2, 0) / variants.length;
|
|
364
|
+
return { sa1, sa2 };
|
|
365
|
+
}
|
|
366
|
+
//# sourceMappingURL=products.js.map
|
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RFC-0017 Phase 2 — In-Soul Variant Pattern admission scorer composition.
|
|
3
|
+
*
|
|
4
|
+
* Implements the variant-scope routing algorithm described in RFC-0017 §5.4
|
|
5
|
+
* and §9 (Phase 2):
|
|
6
|
+
*
|
|
7
|
+
* resolveTargetedVariants(w) = set of (soulId, variantId) pairs declared on
|
|
8
|
+
* the work item via `targetedVariants[]` (URI shape `<soul-id>/<variant-id>`).
|
|
9
|
+
*
|
|
10
|
+
* If no `targetedVariants` declared:
|
|
11
|
+
* Scoring proceeds at soul-aggregate scope (backward-compatible — unchanged
|
|
12
|
+
* from RFC-0009 baseline).
|
|
13
|
+
*
|
|
14
|
+
* Else if |targeted| == 1 (single-variant):
|
|
15
|
+
* Sα₁(w) = scoreSα₁(variant.audienceCharacteristics)
|
|
16
|
+
* Sα₂(w) = scoreSα₂(variant.designOverrides ∪ variant.designImperatives)
|
|
17
|
+
*
|
|
18
|
+
* Else (multi-variant):
|
|
19
|
+
* Per-variant Sα₁ + Sα₂ are aggregated via the Soul's
|
|
20
|
+
* `crossVariantAggregation` rule (per-Soul override; default `min` per
|
|
21
|
+
* RFC-0017 OQ-4 / RFC-0009 §7.2 consistency).
|
|
22
|
+
*
|
|
23
|
+
* This module mirrors the surface shape of `tessellation-admission.ts` so the
|
|
24
|
+
* composite reader can compose the two layers cleanly: tessellation routing
|
|
25
|
+
* picks the Soul scope; variant routing refines that to a variant scope when
|
|
26
|
+
* the work item declares targeted variants of one of the affected souls.
|
|
27
|
+
*
|
|
28
|
+
* **Schema dependency note (Phase 1 not yet shipped):**
|
|
29
|
+
* Phase 1 (AISDLC-352) ships the JSON Schema additions for `variants[]` on
|
|
30
|
+
* Soul DID and `targetedVariants[]` on Work Item, plus the inheritance
|
|
31
|
+
* validator. Phase 2 (this file) defines the in-memory shapes the admission
|
|
32
|
+
* composite needs and the pure routing algorithm. Phase 1 loaders will
|
|
33
|
+
* populate `VariantContext` from on-disk Soul DIDs once they exist. The
|
|
34
|
+
* shapes here parallel the schema layout in RFC-0017 §6.1.
|
|
35
|
+
*
|
|
36
|
+
* @see spec/rfcs/RFC-0017-in-soul-variant-pattern.md §5.4 + §9 + §10
|
|
37
|
+
* @see orchestrator/src/tessellation-admission.ts — sibling Soul-scope router
|
|
38
|
+
*/
|
|
39
|
+
import type { Tessellation } from '@ai-sdlc/reference';
|
|
40
|
+
/**
|
|
41
|
+
* Framework-owned `designOverrides` enum fields per RFC-0017 §6.1 + OQ-5 revisit (2026-05-26).
|
|
42
|
+
*
|
|
43
|
+
* Design Authority editorial pass (Mo, 2026-05-26): `voiceRegister` cut — 6/6 leading design
|
|
44
|
+
* systems (Tailwind, Radix, Material, Carbon, Spectrum, Atlassian) converge on color, spacing,
|
|
45
|
+
* typography, motion, and radii as the core theming surface; none include content register at
|
|
46
|
+
* the visual token layer. `typographyScale`, `motionProfile`, and `radiusProfile` added.
|
|
47
|
+
*
|
|
48
|
+
* These are the only framework-owned field names. Adopters extend via vendor-prefix
|
|
49
|
+
* (see `designOverridesExt` below).
|
|
50
|
+
*/
|
|
51
|
+
export interface VariantDesignOverridesFramework {
|
|
52
|
+
/** Variant-scoped color palette overlay (additive over soul palette). */
|
|
53
|
+
colorPaletteOverlay?: string;
|
|
54
|
+
/** Variant-scoped density profile. */
|
|
55
|
+
densityProfile?: 'compact' | 'comfortable' | 'spacious';
|
|
56
|
+
/** Variant-scoped typography scale. */
|
|
57
|
+
typographyScale?: 'default' | 'large-print' | 'data-dense';
|
|
58
|
+
/** Variant-scoped motion/animation profile. */
|
|
59
|
+
motionProfile?: 'full' | 'reduced' | 'none';
|
|
60
|
+
/** Variant-scoped corner-rounding character (shape, not border stroke weight). */
|
|
61
|
+
radiusProfile?: 'sharp' | 'default' | 'rounded';
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Vendor-prefixed `designOverrides` extension map per RFC-0017 OQ-5.
|
|
65
|
+
* Keys MUST follow reverse-DNS prefix convention (e.g. `acme.com/accessibilityProfile`).
|
|
66
|
+
* Schema validation of the prefix is Phase 1's concern; Phase 2 simply consumes
|
|
67
|
+
* whatever keys are present and treats their truthy presence as a variant-scoped
|
|
68
|
+
* Sα₂ signal contribution.
|
|
69
|
+
*/
|
|
70
|
+
export type VariantDesignOverridesExt = Record<string, string | number | boolean>;
|
|
71
|
+
/**
|
|
72
|
+
* In-memory representation of one variant declared on a Soul DID, parallel to
|
|
73
|
+
* the YAML/JSON schema fields in RFC-0017 §6.1. Phase 1 (AISDLC-352) ships the
|
|
74
|
+
* schema + loader; Phase 2 uses this shape as the contract between loader and
|
|
75
|
+
* the variant-scope router.
|
|
76
|
+
*/
|
|
77
|
+
export interface VariantOverlay {
|
|
78
|
+
/** Variant identifier (kebab-case, unique within the parent Soul). */
|
|
79
|
+
id: string;
|
|
80
|
+
/**
|
|
81
|
+
* Variant-scoped audience characteristics. Feeds Sα₁ Problem/Audience
|
|
82
|
+
* Resonance scoring when the work item targets this variant (RFC-0017
|
|
83
|
+
* §5.4 + §6.1 `targetAudience`).
|
|
84
|
+
*/
|
|
85
|
+
audienceCharacteristics?: {
|
|
86
|
+
segments?: string[];
|
|
87
|
+
sizeRange?: {
|
|
88
|
+
minStaff?: number;
|
|
89
|
+
maxStaff?: number;
|
|
90
|
+
};
|
|
91
|
+
/** Free-form adopter-defined audience fields — preserved as-is for Sα₁. */
|
|
92
|
+
[k: string]: unknown;
|
|
93
|
+
};
|
|
94
|
+
/**
|
|
95
|
+
* Framework-owned design override fields (closed enum per OQ-5).
|
|
96
|
+
*/
|
|
97
|
+
designOverrides?: VariantDesignOverridesFramework;
|
|
98
|
+
/**
|
|
99
|
+
* Vendor-prefixed adopter extensions (OQ-5). Schema validates the prefix;
|
|
100
|
+
* any present key contributes to the variant-scoped Sα₂ surface.
|
|
101
|
+
*/
|
|
102
|
+
designOverridesExt?: VariantDesignOverridesExt;
|
|
103
|
+
/**
|
|
104
|
+
* Variant-scoped Sα₂ design imperatives (layered on top of soul-level
|
|
105
|
+
* imperatives, variant wins on conflict per RFC-0017 §5.4).
|
|
106
|
+
*/
|
|
107
|
+
designImperatives?: string[];
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Per-variant Sα₁ + Sα₂ scores. One entry per variant of one Soul.
|
|
111
|
+
*
|
|
112
|
+
* Phase 1's loader OR a Phase 2/3 scorer populates this — Phase 2's router
|
|
113
|
+
* is agnostic to how the per-variant scores are produced (could be BM25
|
|
114
|
+
* against `audienceCharacteristics.segments`, embedding similarity against
|
|
115
|
+
* `designImperatives`, etc.). The router only knows how to ROUTE among them.
|
|
116
|
+
*/
|
|
117
|
+
export interface VariantScores {
|
|
118
|
+
/** Variant-scoped Sα₁ Problem/Audience Resonance score, in [0, 1]. */
|
|
119
|
+
sa1: number;
|
|
120
|
+
/** Variant-scoped Sα₂ Vibe Coherence score, in [0, 1]. */
|
|
121
|
+
sa2: number;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Per-Soul `variantConfig` block, projected from the
|
|
125
|
+
* `.ai-sdlc/variant-config.yaml` (per-org defaults) + per-Soul overrides
|
|
126
|
+
* in `spec.variantConfig` (RFC-0017 §10.1).
|
|
127
|
+
*
|
|
128
|
+
* Currently surfaces only the OQ-4-resolved knob (cross-variant aggregation).
|
|
129
|
+
* Future Phase-1 phases add `limits`, `lifecycle`, etc.; this interface stays
|
|
130
|
+
* tightly scoped to what the admission router consumes.
|
|
131
|
+
*/
|
|
132
|
+
export interface VariantConfig {
|
|
133
|
+
/**
|
|
134
|
+
* OQ-4 — cross-variant aggregation rule. Default `min` (matches RFC-0009
|
|
135
|
+
* §7.2 cross-soul default per the OQ-4 resolution). Per-Soul override
|
|
136
|
+
* accommodates adopters needing `max` for experimental-variant promotion
|
|
137
|
+
* or `mean` for blended audience studies.
|
|
138
|
+
*/
|
|
139
|
+
crossVariantAggregation?: VariantAggregationRule;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Supported cross-variant aggregation rules. Subset of `Tessellation['crossSoulScoringRule']`
|
|
143
|
+
* — we expose `min`/`max`/`mean` since those are the variant-scope-meaningful options
|
|
144
|
+
* (the `weighted-*` variants are platform-scope-only per RFC-0009 §5.2).
|
|
145
|
+
*/
|
|
146
|
+
export type VariantAggregationRule = 'min' | 'max' | 'mean';
|
|
147
|
+
/**
|
|
148
|
+
* One work item's `targetedVariants[]` declaration. Entries are URI-shaped
|
|
149
|
+
* `<soul-id>/<variant-id>` per RFC-0017 §6.1 (the URI pattern enforced by
|
|
150
|
+
* the schema; we accept the trimmed slug form here because the DID prefix
|
|
151
|
+
* `did:platform-x:soul:` is platform-scoped, not router-scoped).
|
|
152
|
+
*
|
|
153
|
+
* The `did:platform-x:soul:engage/variant:small-utility` URI form from
|
|
154
|
+
* OQ-6 reduces to `engage/small-utility` after the schema's URI parser
|
|
155
|
+
* extracts the soul-id + variant-id segments.
|
|
156
|
+
*/
|
|
157
|
+
export interface WorkItemVariantTargeting {
|
|
158
|
+
/** Canonical work item ID (case-insensitive). E.g. "AISDLC-313". */
|
|
159
|
+
id: string;
|
|
160
|
+
/**
|
|
161
|
+
* Variant references in the schema-accepted form. Each entry MUST be the
|
|
162
|
+
* `<soul-id>/<variant-id>` slug pair (the schema's URI parser normalizes
|
|
163
|
+
* the full `did:...:variant:...` form down to this).
|
|
164
|
+
*/
|
|
165
|
+
targetedVariants?: string[];
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Variant-scope context for the admission composite — everything Phase 2's
|
|
169
|
+
* router needs to refine an already-soul-routed score into a variant-scope
|
|
170
|
+
* score. Built once per pipeline tick from:
|
|
171
|
+
*
|
|
172
|
+
* - The Soul DIDs of every active soul (their `variants[]` declarations)
|
|
173
|
+
* - Pre-computed per-variant Sα₁/Sα₂ scores (Phase 2/3 scorers populate)
|
|
174
|
+
* - The active backlog's work-item targeting (one entry per work item)
|
|
175
|
+
* - Per-Soul `variantConfig` overrides (resolved against per-org defaults)
|
|
176
|
+
*
|
|
177
|
+
* When `undefined` is passed to `computeVariantScopedScores`, the router
|
|
178
|
+
* preserves single-soul Sα₁/Sα₂ semantics unchanged (backward-compatible).
|
|
179
|
+
*/
|
|
180
|
+
export interface VariantContext {
|
|
181
|
+
/**
|
|
182
|
+
* Variant overlays keyed by soulId. Source of truth for which variant IDs
|
|
183
|
+
* are valid per Soul + their `audienceCharacteristics` / `designOverrides`.
|
|
184
|
+
*/
|
|
185
|
+
variantsBySoul: Record<string, VariantOverlay[]>;
|
|
186
|
+
/**
|
|
187
|
+
* Pre-computed per-variant scores, keyed first by soulId then by variantId.
|
|
188
|
+
* Missing entries fall back to the work item's soul-aggregate Sα₁/Sα₂.
|
|
189
|
+
*/
|
|
190
|
+
variantScores: Record<string, Record<string, VariantScores>>;
|
|
191
|
+
/**
|
|
192
|
+
* Work-item targeting entries — one per work item in the active backlog.
|
|
193
|
+
* Missing entries (or empty `targetedVariants`) → backward-compat soul-scope.
|
|
194
|
+
*/
|
|
195
|
+
workItemTargeting?: WorkItemVariantTargeting[];
|
|
196
|
+
/**
|
|
197
|
+
* Per-Soul `variantConfig` overrides (defaults to `{ crossVariantAggregation: 'min' }`
|
|
198
|
+
* when absent). Keyed by soulId.
|
|
199
|
+
*/
|
|
200
|
+
configBySoul?: Record<string, VariantConfig>;
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* One parsed targeted-variant reference. Internal use; surfaced via the router
|
|
204
|
+
* for auditability.
|
|
205
|
+
*/
|
|
206
|
+
export interface ParsedVariantRef {
|
|
207
|
+
soulId: string;
|
|
208
|
+
variantId: string;
|
|
209
|
+
/** The original schema-form string (for round-trip + error reporting). */
|
|
210
|
+
raw: string;
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Parse a targeted-variant reference. Accepts both the schema's accepted forms:
|
|
214
|
+
*
|
|
215
|
+
* 1. Slug-pair: `engage/small-utility` (RFC-0017 §6.1 Work Item schema pattern)
|
|
216
|
+
* 2. Full DID: `did:platform-x:soul:engage/variant:small-utility` (OQ-6)
|
|
217
|
+
*
|
|
218
|
+
* Returns `undefined` for any malformed input — caller's responsibility to
|
|
219
|
+
* surface diagnostics. The schema-side validator is Phase 1's responsibility;
|
|
220
|
+
* the router treats any malformed entry as ignorable (silent skip + caller can
|
|
221
|
+
* count them via the returned `parsedTargets`/`malformedTargets` split if
|
|
222
|
+
* desired).
|
|
223
|
+
*/
|
|
224
|
+
export declare function parseTargetedVariantRef(raw: string): ParsedVariantRef | undefined;
|
|
225
|
+
/**
|
|
226
|
+
* Resolve the set of targeted (soulId, variantId) pairs for a given work item.
|
|
227
|
+
*
|
|
228
|
+
* Algorithm:
|
|
229
|
+
* 1. Find the work item by case-insensitive ID match in `workItemTargeting`.
|
|
230
|
+
* 2. Parse each entry of `targetedVariants[]` via `parseTargetedVariantRef`.
|
|
231
|
+
* 3. Filter parsed refs against `variantsBySoul` — a (soulId, variantId) pair
|
|
232
|
+
* only survives if the soul exists AND the variantId is declared on it.
|
|
233
|
+
* 4. Return the validated intersection (empty = backward-compat soul-scope).
|
|
234
|
+
*
|
|
235
|
+
* Returns an empty array (NOT undefined) in all "no variant routing" cases
|
|
236
|
+
* — the caller distinguishes single-variant / multi-variant / soul-scope
|
|
237
|
+
* paths by checking `.length`.
|
|
238
|
+
*/
|
|
239
|
+
export declare function resolveTargetedVariants(workItemId: string, variantCtx: VariantContext | undefined): ParsedVariantRef[];
|
|
240
|
+
/**
|
|
241
|
+
* Apply a per-Soul `crossVariantAggregation` rule over per-variant scores.
|
|
242
|
+
* Mirrors `applyCrossSoulRule` in `tessellation-admission.ts` but restricted
|
|
243
|
+
* to the three variant-scope-meaningful aggregations (`min` / `max` / `mean`).
|
|
244
|
+
*
|
|
245
|
+
* @param values - Per-variant score samples (one per targeted variant).
|
|
246
|
+
* @param rule - The aggregation rule (defaults to `min` per OQ-4).
|
|
247
|
+
* @param fallback - Returned when `values` is empty.
|
|
248
|
+
*/
|
|
249
|
+
export declare function applyCrossVariantRule(values: number[], rule: VariantAggregationRule | undefined, fallback?: number): number;
|
|
250
|
+
/**
|
|
251
|
+
* Result of variant-scope resolution. Composed with `TessellatedSaResult` by
|
|
252
|
+
* the admission composite — variant routing only takes effect when the work
|
|
253
|
+
* item declares `targetedVariants` AND the variant context is wired in.
|
|
254
|
+
*/
|
|
255
|
+
export interface VariantScopedSaResult {
|
|
256
|
+
/** Resolved Sα₁ value in [0, 1] (variant-scoped or fallback). */
|
|
257
|
+
sa1: number;
|
|
258
|
+
/** Resolved Sα₂ value in [0, 1] (variant-scoped or fallback). */
|
|
259
|
+
sa2: number;
|
|
260
|
+
/**
|
|
261
|
+
* Routing path taken (matches RFC-0017 §5.4 case labels).
|
|
262
|
+
*
|
|
263
|
+
* - `'no-variant-routing'` — no context or no targeted variants declared;
|
|
264
|
+
* fallback Sα₁/Sα₂ preserved (backward-compat).
|
|
265
|
+
* - `'single-variant'` — exactly one targeted variant; per-variant Sα₁/Sα₂ used.
|
|
266
|
+
* - `'multi-variant'` — multiple targeted variants; crossVariantAggregation applied.
|
|
267
|
+
*/
|
|
268
|
+
routingPath: 'no-variant-routing' | 'single-variant' | 'multi-variant';
|
|
269
|
+
/** Targeted variant references that contributed to the aggregation. */
|
|
270
|
+
targetedVariants: ParsedVariantRef[];
|
|
271
|
+
/**
|
|
272
|
+
* The aggregation rule used when `routingPath === 'multi-variant'`. Undefined
|
|
273
|
+
* for `single-variant` and `no-variant-routing` paths. Exposed for audit.
|
|
274
|
+
*/
|
|
275
|
+
aggregationRule?: VariantAggregationRule;
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* Compute the variant-scope-refined Sα₁ + Sα₂ for a work item.
|
|
279
|
+
*
|
|
280
|
+
* This runs AFTER tessellation soul-resolution: the caller has already routed
|
|
281
|
+
* the work item to its target Soul(s) and obtained the soul-aggregate Sα₁ /
|
|
282
|
+
* Sα₂ (the `fallbackSa1` / `fallbackSa2` arguments). Variant routing refines
|
|
283
|
+
* those values when the work item declares `targetedVariants` of one of the
|
|
284
|
+
* affected Souls (RFC-0017 §5.4).
|
|
285
|
+
*
|
|
286
|
+
* **Cross-soul + cross-variant interaction** (RFC-0017 §6.2 last bullet):
|
|
287
|
+
* "When a work item targets variants in MULTIPLE souls, the cross-soul
|
|
288
|
+
* aggregation rule applies at the soul level FIRST, then the cross-variant
|
|
289
|
+
* rule applies within each soul." Phase 2 implements the per-Soul-scope
|
|
290
|
+
* variant aggregation; the per-Soul `crossVariantAggregation` config picks
|
|
291
|
+
* which rule applies inside each Soul. When variants span multiple souls,
|
|
292
|
+
* each soul's per-variant scores are aggregated by THAT soul's config; the
|
|
293
|
+
* resulting per-soul scores are then aggregated by the cross-soul rule
|
|
294
|
+
* (handled by `tessellation-admission.ts`). At the variant-scope layer we
|
|
295
|
+
* therefore aggregate per-Soul, then aggregate per-Soul-results by `min`
|
|
296
|
+
* (the safest cross-soul aggregation default — matches RFC-0009 §7.2).
|
|
297
|
+
*
|
|
298
|
+
* @param workItemId - The canonical work item ID.
|
|
299
|
+
* @param fallbackSa1 - Soul-scope Sα₁ to use when no variant routing applies.
|
|
300
|
+
* @param fallbackSa2 - Soul-scope Sα₂ to use when no variant routing applies.
|
|
301
|
+
* @param variantCtx - Variant-scope context; undefined → backward-compat passthrough.
|
|
302
|
+
*/
|
|
303
|
+
export declare function computeVariantScopedScores(workItemId: string, fallbackSa1: number, fallbackSa2: number, variantCtx: VariantContext | undefined): VariantScopedSaResult;
|
|
304
|
+
/**
|
|
305
|
+
* Helper for callers that already hold a `Tessellation` (sibling SoulScope router)
|
|
306
|
+
* and want to lift Soul-scope tessellation aggregation rule into the
|
|
307
|
+
* variant-scope cross-Soul layer. Currently the variant-scope cross-Soul
|
|
308
|
+
* layer always uses `min` (RFC-0017 §6.2 + RFC-0009 §7.2 safety-critical
|
|
309
|
+
* default). This helper is reserved for a future per-Soul override of the
|
|
310
|
+
* cross-Soul cross-variant layer; today it returns `min` unconditionally.
|
|
311
|
+
*
|
|
312
|
+
* Exported for documentation + so callers can `import` the boundary rather
|
|
313
|
+
* than hardcode `'min'` in two places.
|
|
314
|
+
*/
|
|
315
|
+
export declare function defaultCrossSoulVariantRule(_tessellation?: Tessellation): VariantAggregationRule;
|
|
316
|
+
//# sourceMappingURL=variant-admission.d.ts.map
|