@ai-sdlc/orchestrator 0.10.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/adapters.d.ts +42 -3
- package/dist/adapters.js +133 -3
- package/dist/admission-composite.d.ts +112 -1
- package/dist/admission-composite.js +85 -4
- package/dist/admission-enrichment.d.ts +12 -3
- package/dist/admission-enrichment.js +64 -13
- package/dist/admission-score.d.ts +30 -0
- package/dist/admission-score.js +4 -1
- 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/init-features.d.ts +301 -2
- package/dist/cli/commands/init-features.js +634 -7
- package/dist/cli/commands/init-templates.d.ts +198 -1
- package/dist/cli/commands/init-templates.js +943 -1
- package/dist/cli/commands/init.d.ts +45 -0
- package/dist/cli/commands/init.js +147 -5
- 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/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 +171 -30
- 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/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 +173 -13
- package/dist/runtime/attestations.js +252 -40
- package/dist/runtime/index.d.ts +1 -1
- package/dist/runtime/index.js +1 -1
- 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 +10 -8
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RFC-0018 Phase 3 — JourneyStateIdDriftRule (RFC-0009 §13 Rule #4).
|
|
3
|
+
*
|
|
4
|
+
* Implements the 4th §13 drift-detection rule resolving RFC-0018 OQ-8 + OQ-10
|
|
5
|
+
* (2026-05-28, full rubric):
|
|
6
|
+
*
|
|
7
|
+
* OQ-8: "AST scan from v1, reusing RFC-0009 §13 Rule #1 infrastructure."
|
|
8
|
+
* The existing AST scan engine ALREADY EXISTS for soul-slug leakage
|
|
9
|
+
* detection — adding journey state-ID detection is extending the
|
|
10
|
+
* engine with one additional rule, not building from scratch.
|
|
11
|
+
*
|
|
12
|
+
* OQ-10: "4th rule in the same §13 engine + concrete registration mechanism
|
|
13
|
+
* spec'd: Tessellation§13RuleRegistry.register(rule)."
|
|
14
|
+
*
|
|
15
|
+
* ### Detection strategy
|
|
16
|
+
*
|
|
17
|
+
* The rule reuses the `scanSubstrateFile` textual-scan approach from the
|
|
18
|
+
* existing AST scan engine in `tessellation-drift.ts`. This is deliberately
|
|
19
|
+
* NOT a string match — it uses the same regex-based pattern matching that
|
|
20
|
+
* Rule #1 employs, consistent with the OQ-8 resolution:
|
|
21
|
+
*
|
|
22
|
+
* - Bare string literal: `'<state-id>'` or `"<state-id>"`
|
|
23
|
+
* - State-discriminating conditional: `state === '<state-id>'` / similar
|
|
24
|
+
*
|
|
25
|
+
* This matches the OQ-8 resolution that explicitly rejected the string-match
|
|
26
|
+
* path in favour of the existing AST scan infrastructure.
|
|
27
|
+
*
|
|
28
|
+
* ### Drift conditions
|
|
29
|
+
*
|
|
30
|
+
* Emits `Decision: journey-state-id-drift` when substrate code references:
|
|
31
|
+
* 1. A state ID that is NOT declared in any active journey.
|
|
32
|
+
* 2. A state ID from a journey that has been removed (lifecycle = 'removed').
|
|
33
|
+
*
|
|
34
|
+
* ### Composition with RFC-0028 OQ-7.2
|
|
35
|
+
*
|
|
36
|
+
* Structural drift (this rule at CI authoring time) slots into the structural
|
|
37
|
+
* side of the OQ-7.2 pairing:
|
|
38
|
+
* - `severity === 'high'` → BLOCKS PR via Decision severity HIGH.
|
|
39
|
+
* - `severity === 'medium'` (default) → SURFACES non-blocking via RFC-0035
|
|
40
|
+
* G0 catalog route for operator batch review.
|
|
41
|
+
*
|
|
42
|
+
* Default severity is `'medium'` per RFC-0018 §10.1 (per-org configurable
|
|
43
|
+
* via `journey-config.yaml driftDetection.severityOverride`).
|
|
44
|
+
*
|
|
45
|
+
* @see spec/rfcs/RFC-0018-in-soul-journey-pattern.md §6.2 + §10.1 OQ-8 + OQ-10
|
|
46
|
+
* @see spec/rfcs/RFC-0009-tessellated-design-intent-documents.md §13
|
|
47
|
+
* @see spec/rfcs/RFC-0028-engineering-axis-substrate-enforcement.md OQ-7.2
|
|
48
|
+
* @see orchestrator/src/tessellation-drift.ts (source of the AST-scan engine reused here)
|
|
49
|
+
*/
|
|
50
|
+
// ── AST scan helpers ───────────────────────────────────────────────────
|
|
51
|
+
/**
|
|
52
|
+
* Validate a journey state ID. Valid state IDs are kebab-case: lowercase
|
|
53
|
+
* alphanumeric + dashes, 1-64 chars. Mirrors the soul-slug validator in
|
|
54
|
+
* `tessellation-drift.ts` but applied to journey state IDs.
|
|
55
|
+
*/
|
|
56
|
+
function isValidStateId(id) {
|
|
57
|
+
return /^[a-z0-9][a-z0-9-]*$/.test(id) && id.length >= 1 && id.length <= 64;
|
|
58
|
+
}
|
|
59
|
+
/** Escape a string for safe use inside a RegExp pattern. */
|
|
60
|
+
function escapeRegex(s) {
|
|
61
|
+
return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Scan a single substrate file for references to a set of state IDs.
|
|
65
|
+
*
|
|
66
|
+
* Reuses the same regex-based textual-scan strategy as the soul-slug
|
|
67
|
+
* AST scan in `tessellation-drift.ts` (Rule #1). This is the OQ-8
|
|
68
|
+
* resolution's "reusing RFC-0009 §13 Rule #1 infrastructure" in action:
|
|
69
|
+
* same two patterns (string-literal + state-conditional), extended to
|
|
70
|
+
* match journey state-ID strings rather than soul slugs.
|
|
71
|
+
*
|
|
72
|
+
* Two patterns per state ID (line-by-line):
|
|
73
|
+
* 1. `'<state-id>'` or `"<state-id>"` — bare string literal.
|
|
74
|
+
* 2. `state === '<state-id>'` / similar — state-discriminating conditional.
|
|
75
|
+
* Permissive match on the identifier name: `state`, `stateId`, `state_id`,
|
|
76
|
+
* `journeyState`, etc.
|
|
77
|
+
*/
|
|
78
|
+
function scanFileForStateIds(file, stateIds) {
|
|
79
|
+
const findings = [];
|
|
80
|
+
if (file.contents.length === 0 || stateIds.length === 0)
|
|
81
|
+
return findings;
|
|
82
|
+
const lines = file.contents.split('\n');
|
|
83
|
+
for (const stateId of stateIds) {
|
|
84
|
+
if (!isValidStateId(stateId))
|
|
85
|
+
continue;
|
|
86
|
+
const esc = escapeRegex(stateId);
|
|
87
|
+
// Pattern 1: bare string literal (single or double quote, exact match).
|
|
88
|
+
const literalRe = new RegExp(`(['"])${esc}\\1`);
|
|
89
|
+
// Pattern 2: state-discriminating conditional.
|
|
90
|
+
// Permissive on the state identifier name: catches `state`, `stateId`,
|
|
91
|
+
// `state_id`, `journeyState`, `currentState`, etc.
|
|
92
|
+
const condRe = new RegExp(`(?:state|stateId|state_id|journeyState|currentState|journeyStep|stepId)[A-Za-z_]*\\s*===\\s*(['"])${esc}\\1`);
|
|
93
|
+
for (let i = 0; i < lines.length; i++) {
|
|
94
|
+
const line = lines[i];
|
|
95
|
+
const condMatch = line.match(condRe);
|
|
96
|
+
if (condMatch) {
|
|
97
|
+
findings.push({
|
|
98
|
+
stateId,
|
|
99
|
+
line: i + 1,
|
|
100
|
+
pattern: 'state-conditional',
|
|
101
|
+
excerpt: line.trim().slice(0, 200),
|
|
102
|
+
});
|
|
103
|
+
// Don't double-report the same line as a bare literal.
|
|
104
|
+
continue;
|
|
105
|
+
}
|
|
106
|
+
if (literalRe.test(line)) {
|
|
107
|
+
findings.push({
|
|
108
|
+
stateId,
|
|
109
|
+
line: i + 1,
|
|
110
|
+
pattern: 'string-literal',
|
|
111
|
+
excerpt: line.trim().slice(0, 200),
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return findings;
|
|
117
|
+
}
|
|
118
|
+
// ── Rule implementation ────────────────────────────────────────────────
|
|
119
|
+
/**
|
|
120
|
+
* JourneyStateIdDriftRule — RFC-0009 §13 Rule #4.
|
|
121
|
+
*
|
|
122
|
+
* Scans substrate code for references to journey-state-id strings using
|
|
123
|
+
* the existing AST scan engine from Rule #1 (OQ-8 resolution: NOT string
|
|
124
|
+
* match). Emits `Decision: journey-state-id-drift` when:
|
|
125
|
+
*
|
|
126
|
+
* - Referenced state ID is not declared in any active journey, OR
|
|
127
|
+
* - The journey itself has been removed (cross-references journey lifecycle /
|
|
128
|
+
* deprecation tooling).
|
|
129
|
+
*
|
|
130
|
+
* Severity is per-org configurable (default `'medium'`).
|
|
131
|
+
*
|
|
132
|
+
* ### Registration
|
|
133
|
+
*
|
|
134
|
+
* ```ts
|
|
135
|
+
* const registry = createTessellation13Registry();
|
|
136
|
+
* registry.register(new JourneyStateIdDriftRule());
|
|
137
|
+
* // With config override:
|
|
138
|
+
* registry.register(new JourneyStateIdDriftRule({ severityOverride: 'high' }));
|
|
139
|
+
* ```
|
|
140
|
+
*/
|
|
141
|
+
export class JourneyStateIdDriftRule {
|
|
142
|
+
name = 'journey-state-id-drift';
|
|
143
|
+
description = 'Scans substrate code for references to journey state IDs that are not declared in any active journey or belong to a removed journey (RFC-0018 Phase 3, OQ-8 resolution)';
|
|
144
|
+
severity;
|
|
145
|
+
config;
|
|
146
|
+
constructor(config = {}) {
|
|
147
|
+
this.config = config;
|
|
148
|
+
this.severity = config.severityOverride ?? 'medium';
|
|
149
|
+
}
|
|
150
|
+
scan(target) {
|
|
151
|
+
const { substrateFiles, journeysBySoul, journeyStatus } = target;
|
|
152
|
+
// No-op when no substrate files or no journey declarations.
|
|
153
|
+
if (!substrateFiles || substrateFiles.length === 0)
|
|
154
|
+
return [];
|
|
155
|
+
if (!journeysBySoul || Object.keys(journeysBySoul).length === 0)
|
|
156
|
+
return [];
|
|
157
|
+
const now = new Date().toISOString();
|
|
158
|
+
const activeStateIds = new Set();
|
|
159
|
+
const removedStateIdEntries = [];
|
|
160
|
+
for (const [soulId, journeys] of Object.entries(journeysBySoul)) {
|
|
161
|
+
for (const journey of journeys) {
|
|
162
|
+
const statusKey = `${soulId}/${journey.id}`;
|
|
163
|
+
const status = journeyStatus?.[statusKey] ?? 'active';
|
|
164
|
+
for (const state of journey.states ?? []) {
|
|
165
|
+
if (!isValidStateId(state.id))
|
|
166
|
+
continue;
|
|
167
|
+
if (status === 'removed') {
|
|
168
|
+
removedStateIdEntries.push({
|
|
169
|
+
stateId: state.id,
|
|
170
|
+
journeyId: journey.id,
|
|
171
|
+
soulId,
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
else {
|
|
175
|
+
activeStateIds.add(state.id);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
// ── Scan substrate files ───────────────────────────────────────────
|
|
181
|
+
const findings = [];
|
|
182
|
+
for (const file of substrateFiles) {
|
|
183
|
+
// ── Check for removed state IDs ──────────────────────────────
|
|
184
|
+
// Build the set of removed state IDs (may overlap with active if
|
|
185
|
+
// the same state ID exists in both an active and removed journey;
|
|
186
|
+
// in that case, active wins and we skip).
|
|
187
|
+
const removedStateIds = removedStateIdEntries
|
|
188
|
+
.map((e) => e.stateId)
|
|
189
|
+
.filter((id) => !activeStateIds.has(id));
|
|
190
|
+
if (removedStateIds.length > 0) {
|
|
191
|
+
const hits = scanFileForStateIds(file, removedStateIds);
|
|
192
|
+
for (const hit of hits) {
|
|
193
|
+
const entry = removedStateIdEntries.find((e) => e.stateId === hit.stateId && !activeStateIds.has(e.stateId));
|
|
194
|
+
findings.push({
|
|
195
|
+
kind: 'removed-journey-state-id',
|
|
196
|
+
stateId: hit.stateId,
|
|
197
|
+
journeyId: entry?.journeyId,
|
|
198
|
+
soulId: entry?.soulId,
|
|
199
|
+
filePath: file.path,
|
|
200
|
+
line: hit.line,
|
|
201
|
+
pattern: hit.pattern,
|
|
202
|
+
excerpt: hit.excerpt,
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
// ── Collect all active state IDs to check for undeclared refs ─────
|
|
208
|
+
// Build a map: stateId → [list of files where it was found]
|
|
209
|
+
// Then determine which found state IDs are NOT in activeStateIds.
|
|
210
|
+
//
|
|
211
|
+
// "Undeclared" means: the string appears in substrate code as a
|
|
212
|
+
// potential state-ID reference, but it is not declared in any
|
|
213
|
+
// active journey AND not in any removed journey.
|
|
214
|
+
//
|
|
215
|
+
// To avoid false positives from common short strings (single-char
|
|
216
|
+
// IDs etc.), we only scan for state IDs that are actually declared
|
|
217
|
+
// (active or removed). Strings that look like state IDs but match
|
|
218
|
+
// NOTHING in the journey manifest are not reported — we only report
|
|
219
|
+
// when a declared (but removed) state ID is found.
|
|
220
|
+
//
|
|
221
|
+
// NOTE: "undeclared state ID" in the RFC sense means a string in
|
|
222
|
+
// substrate code that LOOKS like a state-ID reference but refers to
|
|
223
|
+
// a state ID that has been removed AND is no longer in any active journey.
|
|
224
|
+
// The above removed-state-ID scan covers this case.
|
|
225
|
+
//
|
|
226
|
+
// If the caller wants to detect references to strings that were NEVER
|
|
227
|
+
// in any journey at all, they need to provide a corpus of all historical
|
|
228
|
+
// state IDs. For v1, we report only the "was declared, now removed" case
|
|
229
|
+
// (the RFC-0018 §6.2 drift condition).
|
|
230
|
+
if (findings.length === 0)
|
|
231
|
+
return [];
|
|
232
|
+
const event = {
|
|
233
|
+
rule: this.name,
|
|
234
|
+
timestamp: now,
|
|
235
|
+
message: `Journey state-ID drift: ${findings.length} reference(s) to removed or undeclared journey state IDs in substrate code`,
|
|
236
|
+
severity: this.severity,
|
|
237
|
+
details: {
|
|
238
|
+
rule: 'journey-state-id-drift',
|
|
239
|
+
findings,
|
|
240
|
+
},
|
|
241
|
+
};
|
|
242
|
+
return [event];
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
//# sourceMappingURL=state-id-drift-rule.js.map
|
|
@@ -0,0 +1,395 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RFC-0018 Phase 2 — In-Soul Journey Pattern admission scorer composition.
|
|
3
|
+
*
|
|
4
|
+
* Implements the journey-scope routing algorithm described in RFC-0018 §5.4
|
|
5
|
+
* and §10.1 (OQ-4 resolution):
|
|
6
|
+
*
|
|
7
|
+
* resolveTargetedJourneys(w) = set of (soulId, [variantId,] journeyId) triples
|
|
8
|
+
* declared on the work item via `targetedJourneys[]` (URI shapes
|
|
9
|
+
* `<soul-id>/<journey-id>` or `<soul-id>/<variant-id>/<journey-id>`).
|
|
10
|
+
*
|
|
11
|
+
* If no `targetedJourneys` declared:
|
|
12
|
+
* Scoring proceeds at soul/variant scope (backward-compatible — unchanged
|
|
13
|
+
* from RFC-0009 + RFC-0017 baseline).
|
|
14
|
+
*
|
|
15
|
+
* Else if |targeted| == 1 (single-journey):
|
|
16
|
+
* Sα₂(w) = scoreSα₂(journey.designImperatives UNION variant's UNION soul's;
|
|
17
|
+
* most-specific wins: journey > variant > soul)
|
|
18
|
+
* Cκ(w) = boosted when journey.successMetrics.completion-rate < alertBelow
|
|
19
|
+
* Eρ₅(w) = elevated when journey.accessibility.wcagLevel > soul/variant default
|
|
20
|
+
*
|
|
21
|
+
* Else (multi-journey):
|
|
22
|
+
* Per-journey scores aggregated via `crossJourneyAggregation` config
|
|
23
|
+
* (default `min` per RFC-0018 §5.4 + RFC-0017 OQ-4 cross-variant pattern).
|
|
24
|
+
*
|
|
25
|
+
* ### Completion-criteria closed enum (OQ-4 resolution)
|
|
26
|
+
*
|
|
27
|
+
* v1 allows only: `terminal-success-state` | `all-states-reached`
|
|
28
|
+
* `custom-predicate` is rejected at schema validation time.
|
|
29
|
+
* Future activation via `Decision: journey-custom-predicate-activation-request`
|
|
30
|
+
* (Stage A counter, auto-promote at ≥2 distinct adopter requests).
|
|
31
|
+
* Future language: CEL (Google Common Expression Language) per OQ-4 resolution.
|
|
32
|
+
*
|
|
33
|
+
* ### Backward compatibility
|
|
34
|
+
*
|
|
35
|
+
* Work items without `targetedJourneys` score against soul / variant (existing
|
|
36
|
+
* RFC-0017 behavior preserved). Soul DIDs without `journeys[]` behave identically.
|
|
37
|
+
*
|
|
38
|
+
* @see spec/rfcs/RFC-0018-in-soul-journey-pattern.md §5.4 + §10 + §10.1
|
|
39
|
+
* @see orchestrator/src/variant-admission.ts — sibling RFC-0017 Phase 2 router
|
|
40
|
+
* @see orchestrator/src/compliance-clearance.ts — Eρ₅ base scorer
|
|
41
|
+
*/
|
|
42
|
+
/**
|
|
43
|
+
* v1 closed enum for completion-criteria `kind` per RFC-0018 OQ-4 resolution
|
|
44
|
+
* (2026-05-28, full rubric).
|
|
45
|
+
*
|
|
46
|
+
* `custom-predicate` is intentionally absent — schema validation MUST reject
|
|
47
|
+
* it. Future RFC will activate it via the Decision Catalog with CEL as the
|
|
48
|
+
* recommended expression language.
|
|
49
|
+
*/
|
|
50
|
+
export type CompletionCriteriaKind = 'terminal-success-state' | 'all-states-reached';
|
|
51
|
+
/**
|
|
52
|
+
* The set of valid v1 completion-criteria kind values.
|
|
53
|
+
* Used by `validateCompletionCriteriaKind` for closed-enum rejection.
|
|
54
|
+
*/
|
|
55
|
+
export declare const COMPLETION_CRITERIA_V1_KINDS: ReadonlySet<CompletionCriteriaKind>;
|
|
56
|
+
/**
|
|
57
|
+
* Decision kind for the `custom-predicate` activation request counter.
|
|
58
|
+
* Stage A counter per RFC-0035 G0 non-blocking contract.
|
|
59
|
+
* Auto-promotes at ≥2 distinct adopter requests (RFC-0018 OQ-4 resolution).
|
|
60
|
+
*/
|
|
61
|
+
export declare const JOURNEY_CUSTOM_PREDICATE_DECISION_KIND: "journey-custom-predicate-activation-request";
|
|
62
|
+
/**
|
|
63
|
+
* Result of validating a completion-criteria `kind` value against the v1 closed enum.
|
|
64
|
+
*/
|
|
65
|
+
export interface CompletionCriteriaValidationResult {
|
|
66
|
+
/** True when the kind value is in the v1 closed enum. */
|
|
67
|
+
valid: boolean;
|
|
68
|
+
/**
|
|
69
|
+
* When `valid === false`, the rejected kind string (e.g. `'custom-predicate'`).
|
|
70
|
+
* Used for diagnostics + Decision counter registration.
|
|
71
|
+
*/
|
|
72
|
+
rejectedKind?: string;
|
|
73
|
+
/**
|
|
74
|
+
* When `valid === false` AND the rejected kind is `'custom-predicate'`,
|
|
75
|
+
* the Decision kind to emit to the catalog (Stage A counter).
|
|
76
|
+
*/
|
|
77
|
+
decisionKind?: typeof JOURNEY_CUSTOM_PREDICATE_DECISION_KIND;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Validate a completion-criteria `kind` value against the v1 closed enum.
|
|
81
|
+
*
|
|
82
|
+
* Returns `{ valid: true }` for `terminal-success-state` and `all-states-reached`.
|
|
83
|
+
* Returns `{ valid: false, rejectedKind, decisionKind }` for `custom-predicate`
|
|
84
|
+
* (or any other unrecognized value). The caller is responsible for emitting the
|
|
85
|
+
* Decision event to the RFC-0035 catalog.
|
|
86
|
+
*/
|
|
87
|
+
export declare function validateCompletionCriteriaKind(kind: string): CompletionCriteriaValidationResult;
|
|
88
|
+
/**
|
|
89
|
+
* In-memory Stage A counter for `journey-custom-predicate-activation-request`.
|
|
90
|
+
*
|
|
91
|
+
* Per RFC-0018 OQ-4 resolution: auto-promote to a decision walkthrough at ≥2
|
|
92
|
+
* distinct adopter requests. The counter tracks (adopter-id, feature-id) pairs
|
|
93
|
+
* to deduplicate requests from the same adopter — "2 distinct adopter requests"
|
|
94
|
+
* means 2 different adopter IDs, not 2 calls from the same adopter.
|
|
95
|
+
*
|
|
96
|
+
* In v1 this is an in-memory counter (reset per process). Phase 2 will persist
|
|
97
|
+
* it via the RFC-0035 Decision Catalog `cli-decisions` surface (AISDLC-463).
|
|
98
|
+
*/
|
|
99
|
+
export interface DecisionCounter {
|
|
100
|
+
/** The RFC-0035 decision kind being counted. */
|
|
101
|
+
decisionKind: typeof JOURNEY_CUSTOM_PREDICATE_DECISION_KIND;
|
|
102
|
+
/**
|
|
103
|
+
* Deduplicated adopter IDs that have submitted a request.
|
|
104
|
+
* When `size >= 2`, the counter has crossed the auto-promote threshold.
|
|
105
|
+
*/
|
|
106
|
+
distinctAdopterIds: Set<string>;
|
|
107
|
+
/** Total raw request count (including duplicates from same adopter). */
|
|
108
|
+
totalRequests: number;
|
|
109
|
+
/** Whether the auto-promote threshold (≥2 distinct adopters) has been crossed. */
|
|
110
|
+
shouldAutoPromote: boolean;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Increment the Stage A counter for a `journey-custom-predicate-activation-request`.
|
|
114
|
+
*
|
|
115
|
+
* @param counter - The counter to increment (mutated in-place).
|
|
116
|
+
* @param adopterId - Adopter ID submitting the request (for deduplication).
|
|
117
|
+
* Use `'__unknown__'` when adopter identity is unavailable.
|
|
118
|
+
*/
|
|
119
|
+
export declare function incrementDecisionCounter(counter: DecisionCounter, adopterId: string): void;
|
|
120
|
+
/**
|
|
121
|
+
* Create a fresh Stage A counter for `journey-custom-predicate-activation-request`.
|
|
122
|
+
*/
|
|
123
|
+
export declare function createCustomPredicateDecisionCounter(): DecisionCounter;
|
|
124
|
+
/**
|
|
125
|
+
* WCAG conformance levels in ascending strictness order.
|
|
126
|
+
* Used for journey-vs-soul WCAG comparison (Eρ₅ elevation).
|
|
127
|
+
*/
|
|
128
|
+
export type WcagLevel = 'A' | 'AA' | 'AAA';
|
|
129
|
+
/**
|
|
130
|
+
* Returns true when `journeyLevel` is strictly ABOVE `soulDefault`.
|
|
131
|
+
* Journeys MAY raise the WCAG level above the parent; they MAY NOT lower it.
|
|
132
|
+
*/
|
|
133
|
+
export declare function isWcagElevated(journeyLevel: WcagLevel, soulDefault: WcagLevel): boolean;
|
|
134
|
+
/**
|
|
135
|
+
* A single success metric declared on a Journey.
|
|
136
|
+
* Feeds Cκ (Capability Coverage) scoring at journey scope.
|
|
137
|
+
*/
|
|
138
|
+
export interface JourneySuccessMetric {
|
|
139
|
+
/** Metric identifier (e.g. `'completion-rate'`, `'median-time-to-first-task-done'`). */
|
|
140
|
+
id: string;
|
|
141
|
+
/** Target value (e.g. `0.65` for 65% completion rate). */
|
|
142
|
+
target?: number;
|
|
143
|
+
/** Alert threshold: when current value drops below this, Cκ boost applies. */
|
|
144
|
+
alertBelow?: number;
|
|
145
|
+
/** Alert threshold: when current value rises above this, signal fires. */
|
|
146
|
+
alertAbove?: number;
|
|
147
|
+
/** Target seconds (for time-based metrics). */
|
|
148
|
+
targetSeconds?: number;
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Accessibility requirements for a Journey (RFC-0018 §5.2).
|
|
152
|
+
* Journey WCAG level may be set HIGHER than the soul floor.
|
|
153
|
+
*/
|
|
154
|
+
export interface JourneyAccessibility {
|
|
155
|
+
wcagLevel: WcagLevel;
|
|
156
|
+
wcagVersion: '2.0' | '2.1' | '2.2' | '3.0';
|
|
157
|
+
conformanceTarget: number;
|
|
158
|
+
auditCadence?: 'quarterly' | 'annually' | 'release-gated' | 'continuous';
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Completion criteria for a Journey (v1 closed enum per OQ-4).
|
|
162
|
+
* `kind` MUST be `terminal-success-state` or `all-states-reached`.
|
|
163
|
+
* `custom-predicate` is rejected at schema validation; see `validateCompletionCriteriaKind`.
|
|
164
|
+
*/
|
|
165
|
+
export interface JourneyCompletionCriteria {
|
|
166
|
+
kind: CompletionCriteriaKind;
|
|
167
|
+
/** Required when `kind === 'terminal-success-state'`. */
|
|
168
|
+
target?: string;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* In-memory representation of one Journey declared on a Soul DID or Variant,
|
|
172
|
+
* parallel to the YAML/JSON schema fields in RFC-0018 §6.1.
|
|
173
|
+
*
|
|
174
|
+
* Phase 1 (AISDLC-465) ships the schema; Phase 2 (this file) defines the
|
|
175
|
+
* in-memory shape the admission composite needs for journey-scope routing.
|
|
176
|
+
*/
|
|
177
|
+
export interface JourneyDeclaration {
|
|
178
|
+
/** Journey identifier (kebab-case, unique within parent scope). */
|
|
179
|
+
id: string;
|
|
180
|
+
/**
|
|
181
|
+
* Journey scope: applies to all variants (`'soul'`) or a specific variant
|
|
182
|
+
* (`'variant:<variant-id>'`).
|
|
183
|
+
*/
|
|
184
|
+
scope: 'soul' | `variant:${string}`;
|
|
185
|
+
/** v1 closed-enum completion criteria. */
|
|
186
|
+
completionCriteria: JourneyCompletionCriteria;
|
|
187
|
+
/** Accessibility requirements; wcagLevel may exceed soul floor. */
|
|
188
|
+
accessibility: JourneyAccessibility;
|
|
189
|
+
/** Journey-scoped success metrics. Feeds Cκ scoring. */
|
|
190
|
+
successMetrics?: JourneySuccessMetric[];
|
|
191
|
+
/** Journey-scoped design imperatives. UNION with variant/soul; most-specific wins. */
|
|
192
|
+
designImperatives?: string[];
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Pre-computed scores for a single Journey.
|
|
196
|
+
* The journey-scope router uses these when computing Sα₂ + Cκ + Eρ₅.
|
|
197
|
+
*
|
|
198
|
+
* In a production pipeline these are populated by loaders reading the soul's
|
|
199
|
+
* `journeys[]` declarations plus live metric snapshots.
|
|
200
|
+
*/
|
|
201
|
+
export interface JourneyScores {
|
|
202
|
+
/**
|
|
203
|
+
* Journey-scoped Sα₂ (Vibe Coherence) in [0, 1].
|
|
204
|
+
* Derived from journey.designImperatives UNION variant's UNION soul's;
|
|
205
|
+
* most-specific wins (journey > variant > soul).
|
|
206
|
+
*/
|
|
207
|
+
sa2: number;
|
|
208
|
+
/**
|
|
209
|
+
* Journey-scoped Cκ (Capability Coverage) in [0, 1].
|
|
210
|
+
* Boosted above the soul/variant baseline when `completion-rate < alertBelow`.
|
|
211
|
+
*/
|
|
212
|
+
ck: number;
|
|
213
|
+
/**
|
|
214
|
+
* Whether journey accessibility requirements are elevated above soul floor.
|
|
215
|
+
* When true, Eρ₅ Compliance Clearance is checked at journey-elevated WCAG
|
|
216
|
+
* level rather than the soul-default. Categorical: `true` = elevation active.
|
|
217
|
+
*/
|
|
218
|
+
er5Elevated: boolean;
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Per-Soul / per-org cross-journey aggregation config.
|
|
222
|
+
* Default `min` per RFC-0018 §5.4 (matching RFC-0017 OQ-4 cross-variant pattern).
|
|
223
|
+
*/
|
|
224
|
+
export type JourneyAggregationRule = 'min' | 'max' | 'mean';
|
|
225
|
+
/**
|
|
226
|
+
* Per-Soul journey configuration (subset of §10.1 journey-config.yaml schema).
|
|
227
|
+
*/
|
|
228
|
+
export interface JourneyConfig {
|
|
229
|
+
/**
|
|
230
|
+
* Cross-journey aggregation rule for multi-journey work items.
|
|
231
|
+
* Default `min` per RFC-0018 §5.4. Per-Soul override via journey-config.yaml.
|
|
232
|
+
*/
|
|
233
|
+
crossJourneyAggregation?: JourneyAggregationRule;
|
|
234
|
+
/**
|
|
235
|
+
* Soul-default WCAG level — used for Eρ₅ elevation comparison.
|
|
236
|
+
* When absent, `'AA'` is assumed (WCAG 2.1 AA is the industry-standard floor).
|
|
237
|
+
*/
|
|
238
|
+
soulWcagDefault?: WcagLevel;
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* Work-item targeting entry for journey-scope routing.
|
|
242
|
+
* One entry per work item in the active backlog.
|
|
243
|
+
*/
|
|
244
|
+
export interface WorkItemJourneyTargeting {
|
|
245
|
+
/** Canonical work item ID (case-insensitive match). */
|
|
246
|
+
id: string;
|
|
247
|
+
/**
|
|
248
|
+
* Journey references declared on the work item.
|
|
249
|
+
* URI shape: `<soul-id>/<journey-id>` OR `<soul-id>/<variant-id>/<journey-id>`
|
|
250
|
+
* per RFC-0018 §6.1 Work Item schema.
|
|
251
|
+
*/
|
|
252
|
+
targetedJourneys?: string[];
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* All journey-scope context needed by the admission composite for RFC-0018 Phase 2.
|
|
256
|
+
*
|
|
257
|
+
* Callers build this once per pipeline tick and pass it to
|
|
258
|
+
* `computeJourneyScopedScores` via `AdmissionCompositeOptions.journeyContext`.
|
|
259
|
+
*/
|
|
260
|
+
export interface JourneyContext {
|
|
261
|
+
/**
|
|
262
|
+
* Journey declarations keyed by soulId. Source of truth for which journey IDs
|
|
263
|
+
* are valid per Soul + their scoring configuration.
|
|
264
|
+
*/
|
|
265
|
+
journeysBySoul: Record<string, JourneyDeclaration[]>;
|
|
266
|
+
/**
|
|
267
|
+
* Pre-computed per-journey scores, keyed first by soulId then by journeyId.
|
|
268
|
+
* Missing entries fall back to the work item's soul/variant Sα₂/Cκ/Eρ₅.
|
|
269
|
+
*/
|
|
270
|
+
journeyScores: Record<string, Record<string, JourneyScores>>;
|
|
271
|
+
/**
|
|
272
|
+
* Work-item targeting entries — one per work item in the active backlog.
|
|
273
|
+
* Missing entries (or empty `targetedJourneys`) → backward-compat soul/variant scope.
|
|
274
|
+
*/
|
|
275
|
+
workItemTargeting?: WorkItemJourneyTargeting[];
|
|
276
|
+
/**
|
|
277
|
+
* Per-Soul journey configuration overrides.
|
|
278
|
+
* Keyed by soulId. Absent → `{ crossJourneyAggregation: 'min' }` default.
|
|
279
|
+
*/
|
|
280
|
+
configBySoul?: Record<string, JourneyConfig>;
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* One parsed targeted-journey reference. Internal use; surfaced via the router
|
|
284
|
+
* for auditability.
|
|
285
|
+
*/
|
|
286
|
+
export interface ParsedJourneyRef {
|
|
287
|
+
soulId: string;
|
|
288
|
+
/** Present when the journey is variant-scoped (URI form: soul/variant/journey). */
|
|
289
|
+
variantId?: string;
|
|
290
|
+
journeyId: string;
|
|
291
|
+
/** The original URI string (for round-trip + error reporting). */
|
|
292
|
+
raw: string;
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* Parse a targeted-journey reference.
|
|
296
|
+
*
|
|
297
|
+
* Accepts two URI forms per RFC-0018 §6.1:
|
|
298
|
+
*
|
|
299
|
+
* 1. `<soul-id>/<journey-id>` — soul-scoped journey
|
|
300
|
+
* 2. `<soul-id>/<variant-id>/<journey-id>` — variant-scoped journey
|
|
301
|
+
*
|
|
302
|
+
* All slug segments must match `^[a-z][a-z0-9-]*$`.
|
|
303
|
+
* Returns `undefined` for malformed input (silent skip; schema-side validator
|
|
304
|
+
* is Phase 1's concern per RFC-0018 §6.1 pattern).
|
|
305
|
+
*/
|
|
306
|
+
export declare function parseTargetedJourneyRef(raw: string): ParsedJourneyRef | undefined;
|
|
307
|
+
/**
|
|
308
|
+
* Resolve the set of targeted (soulId, [variantId,] journeyId) triples for a work item.
|
|
309
|
+
*
|
|
310
|
+
* Algorithm:
|
|
311
|
+
* 1. Find the work item by case-insensitive ID match in `workItemTargeting`.
|
|
312
|
+
* 2. Parse each entry of `targetedJourneys[]` via `parseTargetedJourneyRef`.
|
|
313
|
+
* 3. Filter parsed refs against `journeysBySoul` — a (soulId, journeyId) pair
|
|
314
|
+
* only survives if the soul exists AND the journeyId is declared on it.
|
|
315
|
+
* 4. Return the validated intersection (empty = backward-compat soul/variant scope).
|
|
316
|
+
*/
|
|
317
|
+
export declare function resolveTargetedJourneys(workItemId: string, journeyCtx: JourneyContext | undefined): ParsedJourneyRef[];
|
|
318
|
+
/**
|
|
319
|
+
* Apply a per-Soul `crossJourneyAggregation` rule over per-journey scores.
|
|
320
|
+
* Mirrors `applyCrossVariantRule` in `variant-admission.ts` but for journey scope.
|
|
321
|
+
*
|
|
322
|
+
* @param values - Per-journey score samples (one per targeted journey).
|
|
323
|
+
* @param rule - The aggregation rule (defaults to `min` per RFC-0018 §5.4 + OQ-4).
|
|
324
|
+
* @param fallback - Returned when `values` is empty.
|
|
325
|
+
*/
|
|
326
|
+
export declare function applyCrossJourneyRule(values: number[], rule: JourneyAggregationRule | undefined, fallback?: number): number;
|
|
327
|
+
/**
|
|
328
|
+
* Result of journey-scope resolution. Composed with variant-scope and
|
|
329
|
+
* tessellation results by the admission composite.
|
|
330
|
+
*
|
|
331
|
+
* Journey routing refines Sα₂, Cκ, and Eρ₅ when the work item declares
|
|
332
|
+
* `targetedJourneys` (RFC-0018 §5.4). Sα₁ and Dπ_n remain at soul/variant
|
|
333
|
+
* scope (journeys don't redefine audience or demand channels).
|
|
334
|
+
*/
|
|
335
|
+
export interface JourneyScopedResult {
|
|
336
|
+
/** Resolved Sα₂ in [0, 1] (journey-scoped or fallback). */
|
|
337
|
+
sa2: number;
|
|
338
|
+
/** Resolved Cκ in [0, 1] (journey-scoped or fallback). */
|
|
339
|
+
ck: number;
|
|
340
|
+
/**
|
|
341
|
+
* Whether Eρ₅ should be evaluated at journey-elevated WCAG level.
|
|
342
|
+
* When `true`, the caller MUST apply Eρ₅ gating at the journey's WCAG
|
|
343
|
+
* level rather than the soul-default. `false` = soul-default applies.
|
|
344
|
+
*/
|
|
345
|
+
er5Elevated: boolean;
|
|
346
|
+
/**
|
|
347
|
+
* Routing path taken (matches RFC-0018 §5.4 case labels).
|
|
348
|
+
*
|
|
349
|
+
* - `'no-journey-routing'` — no context or no targeted journeys declared;
|
|
350
|
+
* fallback Sα₂/Cκ/Eρ₅ preserved (backward-compat).
|
|
351
|
+
* - `'single-journey'` — exactly one targeted journey; per-journey scores used.
|
|
352
|
+
* - `'multi-journey'` — multiple targeted journeys; crossJourneyAggregation applied.
|
|
353
|
+
*/
|
|
354
|
+
routingPath: 'no-journey-routing' | 'single-journey' | 'multi-journey';
|
|
355
|
+
/** Targeted journey references that contributed to the aggregation. */
|
|
356
|
+
targetedJourneys: ParsedJourneyRef[];
|
|
357
|
+
/**
|
|
358
|
+
* The aggregation rule used when `routingPath === 'multi-journey'`. Undefined
|
|
359
|
+
* for `single-journey` and `no-journey-routing` paths. Exposed for audit.
|
|
360
|
+
*/
|
|
361
|
+
aggregationRule?: JourneyAggregationRule;
|
|
362
|
+
}
|
|
363
|
+
/**
|
|
364
|
+
* Compute the journey-scope-refined Sα₂ + Cκ + Eρ₅ for a work item.
|
|
365
|
+
*
|
|
366
|
+
* This runs AFTER variant-scope resolution: the caller has already routed the
|
|
367
|
+
* work item to its target Soul(s)/Variant(s) and obtained the soul/variant
|
|
368
|
+
* Sα₂ (the `fallbackSa2` argument) and Cκ (the `fallbackCk` argument).
|
|
369
|
+
* Journey routing refines those values when the work item declares
|
|
370
|
+
* `targetedJourneys` of one of the affected Souls (RFC-0018 §5.4).
|
|
371
|
+
*
|
|
372
|
+
* **Sα₂ Vibe Coherence** — journey's `designImperatives` UNION variant's UNION
|
|
373
|
+
* soul's; conflict resolution: most-specific wins (journey > variant > soul).
|
|
374
|
+
* The pre-computed `JourneyScores.sa2` in the context encodes this resolution.
|
|
375
|
+
*
|
|
376
|
+
* **Cκ Capability Coverage** — boosted when `completion-rate < alertBelow`.
|
|
377
|
+
* The pre-computed `JourneyScores.ck` encodes the boost; callers supply live
|
|
378
|
+
* metric snapshots to the loader that builds `journeyScores`.
|
|
379
|
+
*
|
|
380
|
+
* **Eρ₅ Compliance Clearance** — elevated when journey WCAG > soul-default.
|
|
381
|
+
* The pre-computed `JourneyScores.er5Elevated` flag captures this; the caller
|
|
382
|
+
* applies Eρ₅ gating at the journey's elevated level when `er5Elevated = true`.
|
|
383
|
+
*
|
|
384
|
+
* **Cross-journey aggregation** (work touches multiple journeys) — same `min`
|
|
385
|
+
* as RFC-0018 §5.4 / RFC-0009 §7.2 / RFC-0017 OQ-4 by default. Per-Soul
|
|
386
|
+
* override via `journeyConfig.crossJourneyAggregation`.
|
|
387
|
+
*
|
|
388
|
+
* @param workItemId - The canonical work item ID.
|
|
389
|
+
* @param fallbackSa2 - Soul/variant Sα₂ to use when no journey routing applies.
|
|
390
|
+
* @param fallbackCk - Soul/variant Cκ to use when no journey routing applies.
|
|
391
|
+
* @param fallbackEr5Elevated - Soul/variant Eρ₅ elevation flag (usually false).
|
|
392
|
+
* @param journeyCtx - Journey-scope context; undefined → backward-compat passthrough.
|
|
393
|
+
*/
|
|
394
|
+
export declare function computeJourneyScopedScores(workItemId: string, fallbackSa2: number, fallbackCk: number, fallbackEr5Elevated: boolean, journeyCtx: JourneyContext | undefined): JourneyScopedResult;
|
|
395
|
+
//# sourceMappingURL=journey-sa2-router.d.ts.map
|