@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
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Admission-subset composite (RFC-0008 §A.6).
|
|
2
|
+
* Admission-subset composite (RFC-0008 §A.6 + RFC-0009 Phase 2.1).
|
|
3
3
|
*
|
|
4
4
|
* The admission gate uses a subset of the full PPA composite:
|
|
5
5
|
*
|
|
@@ -23,11 +23,18 @@
|
|
|
23
23
|
* The `override` bypass is preserved at position 1: when the input has
|
|
24
24
|
* `override: true`, we return `composite = Infinity` without running
|
|
25
25
|
* the admission math — identical to the legacy PPA behaviour.
|
|
26
|
+
*
|
|
27
|
+
* **RFC-0009 Phase 2.1 tessellation extension:**
|
|
28
|
+
* When `AdmissionCompositeOptions.tessellationContext` is provided, the
|
|
29
|
+
* composite routes SA and Eρ₄ (designSystemReadiness) through soul scope
|
|
30
|
+
* per RFC-0009 §6. See `tessellation-admission.ts` for the routing algorithm.
|
|
26
31
|
*/
|
|
27
32
|
import { mapIssueToPriorityInput } from './admission-score.js';
|
|
28
33
|
import { computeAutonomyFactor, computeDefectRiskFactor, computeReadinessFromDesignSystemContext, } from './admission-enrichment.js';
|
|
29
34
|
import { computeAdmissionHumanCurve } from './admission-hc.js';
|
|
30
|
-
import {
|
|
35
|
+
import { computeTessellatedScores, } from './tessellation-admission.js';
|
|
36
|
+
import { computeVariantScopedScores, } from './variant-admission.js';
|
|
37
|
+
import { computeComplianceClearance, } from './compliance-clearance.js';
|
|
31
38
|
const DEFAULT_SIGNAL = 0.5;
|
|
32
39
|
export function computeAdmissionComposite(input, config, options) {
|
|
33
40
|
const timestamp = new Date().toISOString();
|
|
@@ -78,7 +85,7 @@ export function computeAdmissionComposite(input, config, options) {
|
|
|
78
85
|
};
|
|
79
86
|
}
|
|
80
87
|
// ── SA (soul alignment) — SA-1 override (M5) or label-based fallback ──
|
|
81
|
-
const
|
|
88
|
+
const baseSoulAlignment = clamp01(options?.soulAlignmentOverride ?? priorityInput.soulAlignment ?? DEFAULT_SIGNAL);
|
|
82
89
|
// ── D-pi_adjusted ─────────────────────────────────────────────
|
|
83
90
|
const demand = priorityInput.demandSignal ?? DEFAULT_SIGNAL;
|
|
84
91
|
const consensus = priorityInput.teamConsensus ?? DEFAULT_SIGNAL;
|
|
@@ -92,12 +99,49 @@ export function computeAdmissionComposite(input, config, options) {
|
|
|
92
99
|
const complexity = priorityInput.complexity ?? 5;
|
|
93
100
|
const baseExecutionReality = clamp01(1 - complexity / 10);
|
|
94
101
|
const autonomyFactor = computeAutonomyFactor(input.autonomyContext);
|
|
95
|
-
const
|
|
102
|
+
const baseDesignSystemReadiness = computeReadinessFromDesignSystemContext(input.designSystemContext);
|
|
103
|
+
// ── RFC-0009 Phase 2.1: tessellation soul-scope routing ────────
|
|
104
|
+
// When tessellationContext is present, route SA and Eρ₄ through soul
|
|
105
|
+
// scope per RFC-0009 §6. When absent, single-DID path applies.
|
|
106
|
+
//
|
|
107
|
+
// Prefer the canonical workItemId (e.g. "AISDLC-313") over the GitHub-style
|
|
108
|
+
// "#313" so the dep-graph snapshot lookup matches the backlog task ID format.
|
|
109
|
+
const workItemId = input.workItemId ?? `#${input.issueNumber}`;
|
|
110
|
+
const tessellationResult = computeTessellatedScores(workItemId, baseSoulAlignment, baseDesignSystemReadiness, options?.tessellationContext);
|
|
111
|
+
// ── RFC-0017 Phase 2: variant-scope refinement ────────────────
|
|
112
|
+
// When `variantContext` is provided AND the work item declares
|
|
113
|
+
// `targetedVariants[]`, the per-variant Sα₁ + Sα₂ scores REFINE the
|
|
114
|
+
// soul-aggregate `soulAlignment` from tessellation. The combined SA score
|
|
115
|
+
// fed to the composite is the mean of the variant-resolved Sα₁ + Sα₂
|
|
116
|
+
// (both feed soul-alignment per RFC-0008 §A.6 SA pillar definition).
|
|
117
|
+
// When no targeting declared OR variantContext is absent, this is a
|
|
118
|
+
// passthrough — the tessellation result is preserved unchanged
|
|
119
|
+
// (backward-compat per RFC-0017 §7).
|
|
120
|
+
const variantResult = computeVariantScopedScores(workItemId, tessellationResult.soulAlignment, tessellationResult.soulAlignment, options?.variantContext);
|
|
121
|
+
const soulAlignment = variantResult.routingPath === 'no-variant-routing'
|
|
122
|
+
? tessellationResult.soulAlignment
|
|
123
|
+
: combineVariantSaForSoulAlignment(variantResult.sa1, variantResult.sa2);
|
|
124
|
+
const designSystemReadiness = tessellationResult.er4;
|
|
96
125
|
const executionReality = Math.min(baseExecutionReality * autonomyFactor, designSystemReadiness);
|
|
126
|
+
// ── RFC-0009 Phase 4.1: Eρ₅ Compliance Clearance ──────────────
|
|
127
|
+
// Categorical 0/1 gating per §7.1. When the adopter has opted in AND any
|
|
128
|
+
// declared regime is violated, the composite is gated to 0 (work item
|
|
129
|
+
// cannot proceed without resolving the violation). When the adopter has
|
|
130
|
+
// not opted in (default), this returns er5=1 and the composite is
|
|
131
|
+
// unchanged — full backward compatibility with Phase 2/3 behavior.
|
|
132
|
+
//
|
|
133
|
+
// Uses the same `affectedSoulIds` resolved by tessellation routing, so the
|
|
134
|
+
// regime check follows the work item's actual soul scope. Substrate-only
|
|
135
|
+
// work (affectedSoulIds = []) falls through to the `__platform` sentinel.
|
|
136
|
+
const complianceClearanceResult = computeComplianceClearance(workItemId, tessellationResult.affectedSoulIds, options?.complianceClearanceContext);
|
|
97
137
|
// ── HC (tanh-compressed with HC_design) ───────────────────────
|
|
98
138
|
const humanCurve = computeAdmissionHumanCurve(input);
|
|
99
139
|
// ── §A.6 admission subset composite ───────────────────────────
|
|
100
|
-
const composite = soulAlignment *
|
|
140
|
+
const composite = soulAlignment *
|
|
141
|
+
demandPressureAdjusted *
|
|
142
|
+
executionReality *
|
|
143
|
+
complianceClearanceResult.er5 *
|
|
144
|
+
(1 + humanCurve.hcComposite);
|
|
101
145
|
const score = {
|
|
102
146
|
composite,
|
|
103
147
|
dimensions: {
|
|
@@ -114,9 +158,23 @@ export function computeAdmissionComposite(input, config, options) {
|
|
|
114
158
|
// display continuity but do not multiply it into `composite`.
|
|
115
159
|
calibration: clampCalibration(config?.calibrationCoefficient),
|
|
116
160
|
},
|
|
117
|
-
confidence:
|
|
161
|
+
confidence: computeAdmissionConfidence(input, priorityInput, options),
|
|
118
162
|
timestamp,
|
|
119
163
|
};
|
|
164
|
+
// Only include tessellation breakdown when the caller provided a context
|
|
165
|
+
// (non-tessellated path produces routingPath: 'non-tessellated' but we
|
|
166
|
+
// elide the field to preserve backward compat with callers that don't
|
|
167
|
+
// destructure the breakdown exhaustively).
|
|
168
|
+
const tessellationBreakdown = options?.tessellationContext !== undefined ? tessellationResult : undefined;
|
|
169
|
+
// Variant breakdown surfaced ONLY when the caller wired a variant context
|
|
170
|
+
// AND the work item actually targeted variants. Pure backward-compat for
|
|
171
|
+
// callers on the soul-aggregate path.
|
|
172
|
+
const variantBreakdown = options?.variantContext !== undefined && variantResult.routingPath !== 'no-variant-routing'
|
|
173
|
+
? variantResult
|
|
174
|
+
: undefined;
|
|
175
|
+
// Compliance clearance breakdown surfaced ONLY when the adopter opted in
|
|
176
|
+
// (avoids polluting the breakdown shape for Phase 2/3 callers).
|
|
177
|
+
const complianceClearanceBreakdown = options?.complianceClearanceContext?.enabled === true ? complianceClearanceResult : undefined;
|
|
120
178
|
return {
|
|
121
179
|
score,
|
|
122
180
|
breakdown: {
|
|
@@ -129,9 +187,115 @@ export function computeAdmissionComposite(input, config, options) {
|
|
|
129
187
|
designSystemReadiness,
|
|
130
188
|
executionReality,
|
|
131
189
|
humanCurve,
|
|
190
|
+
...(tessellationBreakdown !== undefined ? { tessellation: tessellationBreakdown } : {}),
|
|
191
|
+
...(variantBreakdown !== undefined ? { variant: variantBreakdown } : {}),
|
|
192
|
+
...(complianceClearanceBreakdown !== undefined
|
|
193
|
+
? { complianceClearance: complianceClearanceBreakdown }
|
|
194
|
+
: {}),
|
|
132
195
|
},
|
|
133
196
|
};
|
|
134
197
|
}
|
|
198
|
+
/**
|
|
199
|
+
* Combine variant-scope Sα₁ (audience resonance) + Sα₂ (vibe coherence) into
|
|
200
|
+
* a single soul-alignment value for the admission composite's SA pillar.
|
|
201
|
+
*
|
|
202
|
+
* The legacy admission composite uses a single `soulAlignment` scalar that
|
|
203
|
+
* conceptually rolls Sα₁ + Sα₂ together (RFC-0008 §A.6 SA pillar). When
|
|
204
|
+
* variant routing splits them out per RFC-0017 §5.4, we recombine via the
|
|
205
|
+
* arithmetic mean — equal weighting matches the soul-aggregate combination
|
|
206
|
+
* implied by `pillar-breakdown.ts` and avoids favouring one Sα facet over
|
|
207
|
+
* the other when both are equally variant-bounded.
|
|
208
|
+
*
|
|
209
|
+
* Exported for unit testing + so downstream callers can replicate the
|
|
210
|
+
* combination logic if they need to surface the constituent pieces.
|
|
211
|
+
*/
|
|
212
|
+
export function combineVariantSaForSoulAlignment(sa1, sa2) {
|
|
213
|
+
return clamp01((sa1 + sa2) / 2);
|
|
214
|
+
}
|
|
215
|
+
// ── Admission confidence (AISDLC-172) ──────────────────────────────────
|
|
216
|
+
/**
|
|
217
|
+
* `PriorityInput` fields that the admission mapper (`mapIssueToPriorityInput`)
|
|
218
|
+
* actually populates from issue/backlog signals. The full PPA `SCORABLE_FIELDS`
|
|
219
|
+
* list (used by `computeConfidence` in `priority.ts`) includes runtime-only
|
|
220
|
+
* dimensions like `regulatoryUrgency`, `techInflection`, `marketDivergence`,
|
|
221
|
+
* `meetingDecision`, `budgetUtilization`, and `dependencyClearance` — none of
|
|
222
|
+
* which the admission mapper ever sets. Counting against the full 16-field
|
|
223
|
+
* list capped admit confidence at ~9/16 ≈ 0.56 even for fully-shaped issues
|
|
224
|
+
* (RFC-0009 §13 OQ-9 "0.5 ceiling" bug). The mapper-relevant subset is the
|
|
225
|
+
* correct denominator for the mapper-evidence half of the blend.
|
|
226
|
+
*/
|
|
227
|
+
const ADMISSION_MAPPER_FIELDS = [
|
|
228
|
+
'soulAlignment',
|
|
229
|
+
'demandSignal',
|
|
230
|
+
'teamConsensus',
|
|
231
|
+
'builderConviction',
|
|
232
|
+
'complexity',
|
|
233
|
+
'bugSeverity',
|
|
234
|
+
'explicitPriority',
|
|
235
|
+
'competitiveDrift',
|
|
236
|
+
'customerRequestCount',
|
|
237
|
+
];
|
|
238
|
+
/**
|
|
239
|
+
* RFC-0008 enrichment slots whose presence on `AdmissionInput` indicates
|
|
240
|
+
* an enrichment reader successfully loaded its context. This is the
|
|
241
|
+
* "enrichment-success signal" referenced in the OQ-9 hypothesis:
|
|
242
|
+
*
|
|
243
|
+
* - `designSystemContext` ← DSB loader (catalog/token coverage)
|
|
244
|
+
* - `autonomyContext` ← AutonomyPolicy (DID-driven) loader
|
|
245
|
+
* - `codeAreaQuality` ← code-area metrics loader
|
|
246
|
+
* - `designAuthoritySignal` ← maintainers/principals loader
|
|
247
|
+
* - `soulAlignmentOverride` ← soul-tracks SA-1 loader (M5 path)
|
|
248
|
+
*
|
|
249
|
+
* Total slots is `5`. Each loaded slot contributes `1/5` to the
|
|
250
|
+
* enrichment-evidence half of the confidence blend.
|
|
251
|
+
*/
|
|
252
|
+
const ADMISSION_ENRICHMENT_SLOT_COUNT = 5;
|
|
253
|
+
function countLoadedEnrichmentSlots(input, options) {
|
|
254
|
+
let loaded = 0;
|
|
255
|
+
if (input.designSystemContext)
|
|
256
|
+
loaded++;
|
|
257
|
+
if (input.autonomyContext)
|
|
258
|
+
loaded++;
|
|
259
|
+
if (input.codeAreaQuality)
|
|
260
|
+
loaded++;
|
|
261
|
+
if (input.designAuthoritySignal)
|
|
262
|
+
loaded++;
|
|
263
|
+
if (options?.soulAlignmentOverride !== undefined)
|
|
264
|
+
loaded++;
|
|
265
|
+
return loaded;
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* Compute admission confidence in [0, 1] as a 50/50 blend of two
|
|
269
|
+
* independent evidence channels:
|
|
270
|
+
*
|
|
271
|
+
* 1. **Mapper coverage** — fraction of `ADMISSION_MAPPER_FIELDS`
|
|
272
|
+
* explicitly populated on the derived `PriorityInput`. Captures
|
|
273
|
+
* "how much issue/backlog signal did `mapIssueToPriorityInput`
|
|
274
|
+
* extract".
|
|
275
|
+
*
|
|
276
|
+
* 2. **Enrichment loaded** — fraction of RFC-0008 enrichment slots
|
|
277
|
+
* present on the input (or supplied via `options`). Captures "how
|
|
278
|
+
* much external context did the enrichment readers contribute".
|
|
279
|
+
*
|
|
280
|
+
* Bug fixed (AISDLC-172 / RFC-0009 §13 OQ-9): previously
|
|
281
|
+
* `computeConfidence(priorityInput)` from `priority.ts` was used, which
|
|
282
|
+
* counts against the full 16-field `SCORABLE_FIELDS` list and ignores
|
|
283
|
+
* enrichment success entirely. The result was a hard ~0.5 ceiling on
|
|
284
|
+
* admit confidence even when DID + DSB + maintainers + soul-tracks all
|
|
285
|
+
* loaded — those four positive observations contributed exactly zero
|
|
286
|
+
* to the formula's denominator and zero to its numerator.
|
|
287
|
+
*/
|
|
288
|
+
export function computeAdmissionConfidence(input, priorityInput, options) {
|
|
289
|
+
let providedMapper = 0;
|
|
290
|
+
for (const field of ADMISSION_MAPPER_FIELDS) {
|
|
291
|
+
if (priorityInput[field] !== undefined)
|
|
292
|
+
providedMapper++;
|
|
293
|
+
}
|
|
294
|
+
const mapperFraction = providedMapper / ADMISSION_MAPPER_FIELDS.length;
|
|
295
|
+
const loadedEnrichment = countLoadedEnrichmentSlots(input, options);
|
|
296
|
+
const enrichmentFraction = loadedEnrichment / ADMISSION_ENRICHMENT_SLOT_COUNT;
|
|
297
|
+
return 0.5 * mapperFraction + 0.5 * enrichmentFraction;
|
|
298
|
+
}
|
|
135
299
|
function clamp01(value) {
|
|
136
300
|
return Math.min(1, Math.max(0, value));
|
|
137
301
|
}
|
|
@@ -92,15 +92,24 @@ export declare function complexityToAutonomyLevel(complexity: number): number;
|
|
|
92
92
|
*/
|
|
93
93
|
export declare function computeAutonomyFactor(ctx: AutonomyContext | undefined): number;
|
|
94
94
|
/**
|
|
95
|
-
* Compute the C5 design-authority weight per §A.5
|
|
95
|
+
* Compute the C5 design-authority weight per §A.5 (Source 1) plus
|
|
96
|
+
* the RFC-0008 §C5 Source 3 compliance-assessment signal.
|
|
96
97
|
*
|
|
98
|
+
* Source 1 (principal participation):
|
|
97
99
|
* non-authority → 0.0
|
|
98
100
|
* authority + positive → +0.6 × modulation
|
|
99
101
|
* authority + negative → -0.4 × modulation
|
|
100
102
|
* authority + no type → +0.3 × modulation
|
|
101
103
|
*
|
|
102
|
-
*
|
|
103
|
-
*
|
|
104
|
+
* where `modulation = 1.2 - areaComplianceScore` when the score is
|
|
105
|
+
* supplied, else `1.0` (unmodulated base weight).
|
|
106
|
+
*
|
|
107
|
+
* Source 3 (compliance assessment — additive):
|
|
108
|
+
* `signal.complianceSignal` contributes directly when present (see
|
|
109
|
+
* `buildDesignAuthoritySignal`). This fires from DSB health data
|
|
110
|
+
* alone — no principal participation required — so a fully-loaded DSB
|
|
111
|
+
* with high token compliance produces `hcDesign > 0` regardless of
|
|
112
|
+
* whether a design-authority principal commented on the issue.
|
|
104
113
|
*/
|
|
105
114
|
export declare function computeDesignAuthorityWeight(signal: DesignAuthoritySignal | undefined): number;
|
|
106
115
|
/**
|
|
@@ -204,37 +204,98 @@ const DESIGN_AUTHORITY_BASE_WEIGHT = Object.freeze({
|
|
|
204
204
|
unspecified: 0.3,
|
|
205
205
|
});
|
|
206
206
|
/**
|
|
207
|
-
* Compute the C5 design-authority weight per §A.5
|
|
207
|
+
* Compute the C5 design-authority weight per §A.5 (Source 1) plus
|
|
208
|
+
* the RFC-0008 §C5 Source 3 compliance-assessment signal.
|
|
208
209
|
*
|
|
210
|
+
* Source 1 (principal participation):
|
|
209
211
|
* non-authority → 0.0
|
|
210
212
|
* authority + positive → +0.6 × modulation
|
|
211
213
|
* authority + negative → -0.4 × modulation
|
|
212
214
|
* authority + no type → +0.3 × modulation
|
|
213
215
|
*
|
|
214
|
-
*
|
|
215
|
-
*
|
|
216
|
+
* where `modulation = 1.2 - areaComplianceScore` when the score is
|
|
217
|
+
* supplied, else `1.0` (unmodulated base weight).
|
|
218
|
+
*
|
|
219
|
+
* Source 3 (compliance assessment — additive):
|
|
220
|
+
* `signal.complianceSignal` contributes directly when present (see
|
|
221
|
+
* `buildDesignAuthoritySignal`). This fires from DSB health data
|
|
222
|
+
* alone — no principal participation required — so a fully-loaded DSB
|
|
223
|
+
* with high token compliance produces `hcDesign > 0` regardless of
|
|
224
|
+
* whether a design-authority principal commented on the issue.
|
|
216
225
|
*/
|
|
217
226
|
export function computeDesignAuthorityWeight(signal) {
|
|
218
|
-
if (!signal
|
|
227
|
+
if (!signal)
|
|
219
228
|
return 0;
|
|
220
|
-
|
|
221
|
-
const
|
|
222
|
-
|
|
223
|
-
|
|
229
|
+
// Source 1: principal-participation weight.
|
|
230
|
+
const participationWeight = signal.isDesignAuthority
|
|
231
|
+
? (() => {
|
|
232
|
+
const signalType = signal.signalType ?? 'unspecified';
|
|
233
|
+
const base = DESIGN_AUTHORITY_BASE_WEIGHT[signalType];
|
|
234
|
+
const modulation = signal.areaComplianceScore !== undefined ? 1.2 - signal.areaComplianceScore : 1;
|
|
235
|
+
return base * modulation;
|
|
236
|
+
})()
|
|
237
|
+
: 0;
|
|
238
|
+
// Source 3: compliance-assessment signal (additive).
|
|
239
|
+
const complianceWeight = signal.complianceSignal ?? 0;
|
|
240
|
+
return participationWeight + complianceWeight;
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* RFC-0008 §C5 Source 3 — map DSB token-compliance coverage to a
|
|
244
|
+
* small automatic signal for HC_design.
|
|
245
|
+
*
|
|
246
|
+
* >= 0.8 (80 %) → +0.3 (design system is healthy — small positive)
|
|
247
|
+
* < 0.4 (40 %) → −0.2 (design system is fragile — small negative)
|
|
248
|
+
* otherwise → 0.0 (neutral)
|
|
249
|
+
*
|
|
250
|
+
* The signal is intentionally small so it cannot outweigh Source 1
|
|
251
|
+
* (principal-participation, which carries base weights up to ±0.6).
|
|
252
|
+
* A DSB with missing status data returns 0 (graceful degradation).
|
|
253
|
+
*/
|
|
254
|
+
function computeComplianceSignal(binding) {
|
|
255
|
+
const rawCoverage = binding.status?.tokenCompliance?.currentCoverage;
|
|
256
|
+
if (rawCoverage === undefined || Number.isNaN(rawCoverage))
|
|
257
|
+
return 0;
|
|
258
|
+
// Normalise: values > 1 are percent (0-100), values ≤ 1 are already fractions.
|
|
259
|
+
const coverage = rawCoverage > 1 ? rawCoverage / 100 : rawCoverage;
|
|
260
|
+
const clamped = Math.min(1, Math.max(0, coverage));
|
|
261
|
+
if (clamped >= 0.8)
|
|
262
|
+
return 0.3;
|
|
263
|
+
if (clamped < 0.4)
|
|
264
|
+
return -0.2;
|
|
265
|
+
return 0;
|
|
224
266
|
}
|
|
225
267
|
function buildDesignAuthoritySignal(input, ctx) {
|
|
226
268
|
if (!ctx.designSystemBinding)
|
|
227
269
|
return undefined;
|
|
270
|
+
// AISDLC-171: surface whether the DSB declares any design authority
|
|
271
|
+
// principals at all. This is a diagnostic flag — it does NOT participate
|
|
272
|
+
// in the HC_design weight calculation (per RFC-0008 §14.2, only
|
|
273
|
+
// principals who participate as author/commenter can emit HC_design via
|
|
274
|
+
// Source 1). The flag lets pillarBreakdown distinguish "DSB has no
|
|
275
|
+
// design authority structure" from "DSB has design authority but no
|
|
276
|
+
// principal participated in this issue".
|
|
277
|
+
const principalsDeclared = (ctx.designSystemBinding.spec.stewardship.designAuthority.principals?.length ?? 0) > 0;
|
|
228
278
|
const { isDesignAuthority, signalType } = checkDesignAuthority({
|
|
229
279
|
authorLogin: input.authorLogin,
|
|
230
280
|
commenterLogins: input.commenterLogins,
|
|
231
281
|
labels: input.labels,
|
|
232
282
|
}, ctx.designSystemBinding);
|
|
233
|
-
|
|
234
|
-
|
|
283
|
+
// RFC-0008 §C5 Source 3: compliance-assessment auto-signal from DSB health.
|
|
284
|
+
// Fires regardless of principal participation — gives a fully-loaded DSB
|
|
285
|
+
// a non-zero hcDesign even when no design-authority principal commented.
|
|
286
|
+
const complianceSignal = computeComplianceSignal(ctx.designSystemBinding);
|
|
287
|
+
if (!isDesignAuthority) {
|
|
288
|
+
return {
|
|
289
|
+
isDesignAuthority: false,
|
|
290
|
+
principalsDeclared,
|
|
291
|
+
...(complianceSignal !== 0 ? { complianceSignal } : {}),
|
|
292
|
+
};
|
|
293
|
+
}
|
|
235
294
|
return {
|
|
236
295
|
isDesignAuthority: true,
|
|
237
296
|
signalType,
|
|
297
|
+
principalsDeclared,
|
|
298
|
+
...(complianceSignal !== 0 ? { complianceSignal } : {}),
|
|
238
299
|
...(ctx.areaComplianceScore !== undefined
|
|
239
300
|
? { areaComplianceScore: ctx.areaComplianceScore }
|
|
240
301
|
: {}),
|
package/dist/admission-hc.d.ts
CHANGED
|
@@ -34,8 +34,27 @@ export interface AdmissionHumanCurveResult {
|
|
|
34
34
|
hcConsensus: number;
|
|
35
35
|
/** Signed meeting-decision signal in [-1, 1] (0 = neutral when absent). */
|
|
36
36
|
hcDecision: number;
|
|
37
|
-
/**
|
|
37
|
+
/**
|
|
38
|
+
* Signed design-authority signal in [-1, 1].
|
|
39
|
+
*
|
|
40
|
+
* AISDLC-171: this channel ONLY fires when one of the issue's
|
|
41
|
+
* participants (author or commenters) is a principal listed in
|
|
42
|
+
* `DesignSystemBinding.spec.stewardship.designAuthority.principals`.
|
|
43
|
+
* Per RFC-0008 §14.2, non-principal participants' design opinions
|
|
44
|
+
* route through `hcConsensus` instead — `hcDesign` carries
|
|
45
|
+
* specifically the design-authority leadership signal. To distinguish
|
|
46
|
+
* "no DSB at all" from "DSB exists but no design principal
|
|
47
|
+
* participated", consult `designAuthorityConfigured` on this result
|
|
48
|
+
* (and on `pillarBreakdown.shared.hcComposite`).
|
|
49
|
+
*/
|
|
38
50
|
hcDesign: number;
|
|
51
|
+
/**
|
|
52
|
+
* Diagnostic flag (AISDLC-171) — true when the resolved DSB declared
|
|
53
|
+
* `stewardship.designAuthority.principals` entries. Always undefined
|
|
54
|
+
* when no DSB was supplied (preDesignSystem). Surfaces the
|
|
55
|
+
* "configured but inactive" state without altering hcDesign weight.
|
|
56
|
+
*/
|
|
57
|
+
designAuthorityConfigured?: boolean;
|
|
39
58
|
/** Weighted sum before tanh. */
|
|
40
59
|
hcRaw: number;
|
|
41
60
|
/** `tanh(hcRaw)` — the HC value consumed by the admission composite. */
|
package/dist/admission-hc.js
CHANGED
|
@@ -70,12 +70,23 @@ export function computeAdmissionHumanCurve(input) {
|
|
|
70
70
|
const hcConsensus = deriveHcConsensus(input);
|
|
71
71
|
const hcDecision = deriveHcDecision(input);
|
|
72
72
|
const hcDesign = deriveHcDesign(input.designAuthoritySignal);
|
|
73
|
+
// AISDLC-171: surface the diagnostic flag from the enriched signal so
|
|
74
|
+
// pillarBreakdown can render the "configured but inactive" state.
|
|
75
|
+
const designAuthorityConfigured = input.designAuthoritySignal?.principalsDeclared;
|
|
73
76
|
const hcRaw = HC_WEIGHTS.explicit * hcExplicit +
|
|
74
77
|
HC_WEIGHTS.consensus * hcConsensus +
|
|
75
78
|
HC_WEIGHTS.decision * hcDecision +
|
|
76
79
|
HC_WEIGHTS.design * hcDesign;
|
|
77
80
|
const hcComposite = Math.tanh(hcRaw);
|
|
78
|
-
return {
|
|
81
|
+
return {
|
|
82
|
+
hcExplicit,
|
|
83
|
+
hcConsensus,
|
|
84
|
+
hcDecision,
|
|
85
|
+
hcDesign,
|
|
86
|
+
hcRaw,
|
|
87
|
+
hcComposite,
|
|
88
|
+
...(designAuthorityConfigured !== undefined ? { designAuthorityConfigured } : {}),
|
|
89
|
+
};
|
|
79
90
|
}
|
|
80
91
|
function clamp(value, min, max) {
|
|
81
92
|
return Math.min(max, Math.max(min, value));
|
|
@@ -25,6 +25,18 @@ export interface AdmissionInput {
|
|
|
25
25
|
commentCount: number;
|
|
26
26
|
/** ISO timestamp of issue creation. */
|
|
27
27
|
createdAt: string;
|
|
28
|
+
/**
|
|
29
|
+
* Canonical work item ID for dep-graph lookups (RFC-0014 / RFC-0009 Phase 2.1).
|
|
30
|
+
*
|
|
31
|
+
* When present, used instead of `#${issueNumber}` to match the work item
|
|
32
|
+
* against dep-graph snapshot entries (which use backlog task IDs like
|
|
33
|
+
* `AISDLC-313`). Backlog adapters set this from the task's frontmatter `id`.
|
|
34
|
+
*
|
|
35
|
+
* Absent for GitHub-issue based inputs — the admission composite falls back
|
|
36
|
+
* to `#${issueNumber}` which is consistent with `mapIssueToPriorityInput`'s
|
|
37
|
+
* `itemId` field.
|
|
38
|
+
*/
|
|
39
|
+
workItemId?: string;
|
|
28
40
|
/** GitHub author_association — determines trust-based signal boosting. */
|
|
29
41
|
authorAssociation?: AuthorAssociation;
|
|
30
42
|
/** GitHub login of the issue author (used by C5 principal match). */
|
|
@@ -102,6 +114,38 @@ export interface DesignAuthoritySignal {
|
|
|
102
114
|
signalType?: DesignAuthoritySignalType;
|
|
103
115
|
/** The issue's code area compliance score in [0, 1] (used to modulate weight). */
|
|
104
116
|
areaComplianceScore?: number;
|
|
117
|
+
/**
|
|
118
|
+
* Diagnostic flag (AISDLC-171) — true when the resolved DSB declared
|
|
119
|
+
* one or more `stewardship.designAuthority.principals` entries,
|
|
120
|
+
* regardless of whether any of them participated in this issue.
|
|
121
|
+
*
|
|
122
|
+
* This is intentionally NOT consumed by `computeDesignAuthorityWeight`
|
|
123
|
+
* — RFC-0008 §14.2 requires principal participation for HC_design to
|
|
124
|
+
* fire at any weight. The flag exists so `pillarBreakdown.shared.
|
|
125
|
+
* hcComposite.designAuthorityConfigured` can surface "design authority
|
|
126
|
+
* is configured but absent from this issue" — distinct from "no
|
|
127
|
+
* design authority structure exists at all" — without violating the
|
|
128
|
+
* RFC's §14.2 weighting constraint.
|
|
129
|
+
*/
|
|
130
|
+
principalsDeclared?: boolean;
|
|
131
|
+
/**
|
|
132
|
+
* RFC-0008 §C5 Source 3 — automated compliance-assessment signal in [-1, 1].
|
|
133
|
+
*
|
|
134
|
+
* Populated by `buildDesignAuthoritySignal` when the resolved DSB carries
|
|
135
|
+
* `status.tokenCompliance.currentCoverage`:
|
|
136
|
+
* >= 0.8 (80 %) → small positive signal (+0.3): design system is healthy here
|
|
137
|
+
* < 0.4 (40 %) → small negative signal (-0.2): design system is fragile here
|
|
138
|
+
* otherwise → 0 (neutral)
|
|
139
|
+
*
|
|
140
|
+
* This signal fires from the DSB health data alone — no principal participation
|
|
141
|
+
* required. It is additive to the principal-participation weight in
|
|
142
|
+
* `computeDesignAuthorityWeight`, so a fully-loaded DSB with high compliance
|
|
143
|
+
* produces `hcDesign > 0` even when no design-authority principal commented.
|
|
144
|
+
*
|
|
145
|
+
* Absent (undefined) when no DSB is resolved or the DSB lacks token-compliance
|
|
146
|
+
* status — callers treat absence the same as 0.
|
|
147
|
+
*/
|
|
148
|
+
complianceSignal?: number;
|
|
105
149
|
}
|
|
106
150
|
export interface AdmissionThresholds {
|
|
107
151
|
minimumScore: number;
|
package/dist/admission-score.js
CHANGED
|
@@ -24,7 +24,13 @@ export function mapIssueToPriorityInput(input) {
|
|
|
24
24
|
const backlog = input.backlogContext;
|
|
25
25
|
// ── Backlog status veto ─────────────────────────────────────
|
|
26
26
|
// Drafts aren't ready to admit; orchestrator should ignore them.
|
|
27
|
-
|
|
27
|
+
// RFC-0011 Phase 4 (AISDLC-115.5): the same veto applies to
|
|
28
|
+
// `Needs Clarification` — running PPA on an unready issue burns
|
|
29
|
+
// scoring effort that gets invalidated on clarification (RFC §2.3 +
|
|
30
|
+
// §7.2). The PPA admission step short-circuits with soulAlignment=0
|
|
31
|
+
// so the composite scorer treats the issue as not-admissible without
|
|
32
|
+
// calling out to the design / autonomy / trust enrichment layers.
|
|
33
|
+
if (backlog?.status === 'Draft' || backlog?.status === 'Needs Clarification') {
|
|
28
34
|
return {
|
|
29
35
|
itemId: `#${input.issueNumber}`,
|
|
30
36
|
title: input.title,
|
|
@@ -39,7 +45,10 @@ export function mapIssueToPriorityInput(input) {
|
|
|
39
45
|
const isTrusted = assoc === 'OWNER' || assoc === 'MEMBER' || assoc === 'COLLABORATOR';
|
|
40
46
|
const isContributor = assoc === 'CONTRIBUTOR';
|
|
41
47
|
// ── Complexity from issue body, AC count, or backlog context ─
|
|
42
|
-
|
|
48
|
+
// Horizontal-whitespace classes ([ \t]) around \n+ so the sub-patterns can't
|
|
49
|
+
// overlap (\s includes \n) — avoids polynomial backtracking on attacker-
|
|
50
|
+
// controlled issue bodies (CodeQL js/polynomial-redos).
|
|
51
|
+
const complexityMatch = input.body?.match(/###?[ \t]*Complexity[ \t]*\n+[ \t]*(\d+)/i);
|
|
43
52
|
let complexity = complexityMatch ? Number(complexityMatch[1]) : undefined;
|
|
44
53
|
// Backlog tasks rarely include a `### Complexity` header — fall back to AC count
|
|
45
54
|
// (each AC is roughly one logical unit; clamp at 10).
|
|
@@ -18,6 +18,36 @@
|
|
|
18
18
|
*/
|
|
19
19
|
import type { PriorityInput, QualityFlag } from '@ai-sdlc/reference';
|
|
20
20
|
import { type AdmissionInput } from './admission-score.js';
|
|
21
|
+
/**
|
|
22
|
+
* Extract a code-area string from a list of file/path references.
|
|
23
|
+
*
|
|
24
|
+
* Algorithm:
|
|
25
|
+
* 1. Filter references down to path-like strings (not URLs, not AISDLC-N
|
|
26
|
+
* IDs, not RFC-NNNN IDs) — the path-like entries are the ones that
|
|
27
|
+
* carry blast-radius signal.
|
|
28
|
+
* 2. Compute the deepest common path prefix across all filtered paths
|
|
29
|
+
* at the directory level (e.g. `pipeline-cli/src/orchestrator/filters/x.ts`
|
|
30
|
+
* + `pipeline-cli/src/orchestrator/loop.ts` → `pipeline-cli/src/orchestrator`).
|
|
31
|
+
* 3. Return the prefix, or `undefined` when there are no path references.
|
|
32
|
+
*
|
|
33
|
+
* The caller uses the result to populate `EnrichmentContext.codeArea` so
|
|
34
|
+
* `buildCodeAreaQuality()` can look up per-area metrics instead of the
|
|
35
|
+
* uniform Eρ variance of 0.30.
|
|
36
|
+
*
|
|
37
|
+
* @param references Raw reference strings from frontmatter `references:` AND
|
|
38
|
+
* any `## References` body section — callers are responsible
|
|
39
|
+
* for merging both sources before calling here.
|
|
40
|
+
*/
|
|
41
|
+
export declare function extractCodeAreaFromReferences(references: string[]): string | undefined;
|
|
42
|
+
/**
|
|
43
|
+
* Parse file-path references from a `## References` markdown section.
|
|
44
|
+
*
|
|
45
|
+
* The body format is a bullet list where each item may be a bare path,
|
|
46
|
+
* a backtick-quoted path, a description with an inline path, or a mix.
|
|
47
|
+
* We extract the first backtick-quoted segment or the first slash-
|
|
48
|
+
* containing word from each bullet.
|
|
49
|
+
*/
|
|
50
|
+
export declare function parseBodyReferences(body: string): string[];
|
|
21
51
|
export interface BacklogAcceptanceCriterion {
|
|
22
52
|
index: number;
|
|
23
53
|
text: string;
|
|
@@ -38,6 +68,11 @@ export interface BacklogTaskSnapshot {
|
|
|
38
68
|
createdBy?: string;
|
|
39
69
|
acceptanceCriteria: BacklogAcceptanceCriterion[];
|
|
40
70
|
references: string[];
|
|
71
|
+
/**
|
|
72
|
+
* References extracted from the `## References` body section.
|
|
73
|
+
* Merged with frontmatter `references` when computing `codeArea`.
|
|
74
|
+
*/
|
|
75
|
+
bodyReferences: string[];
|
|
41
76
|
/** Task IDs this task is blocked by (frontmatter `dependencies`). */
|
|
42
77
|
dependencies: string[];
|
|
43
78
|
/** Filesystem path the snapshot was read from. */
|
|
@@ -83,6 +118,16 @@ export interface BacklogAdmissionMapping {
|
|
|
83
118
|
priorityInputOverrides: Partial<PriorityInput>;
|
|
84
119
|
/** Quality flags surfaced for renderers (zombie close, etc). */
|
|
85
120
|
qualityFlags: QualityFlag[];
|
|
121
|
+
/**
|
|
122
|
+
* Deepest common path prefix computed from all references in the task
|
|
123
|
+
* (frontmatter `references:` + `## References` body section).
|
|
124
|
+
*
|
|
125
|
+
* Pass to `EnrichmentContext.codeArea` when calling `enrichAdmissionInput()`
|
|
126
|
+
* so `buildCodeAreaQuality()` can look up per-area metrics instead of the
|
|
127
|
+
* uniform Eρ variance of 0.30. Undefined when the task has no file-path
|
|
128
|
+
* references — callers should fall through to the uniform default.
|
|
129
|
+
*/
|
|
130
|
+
codeArea: string | undefined;
|
|
86
131
|
}
|
|
87
132
|
/**
|
|
88
133
|
* Map a Backlog snapshot onto an `AdmissionInput` plus the
|