@ai-sdlc/orchestrator 0.5.0 → 0.9.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/action-enforcement.d.ts +26 -0
- package/dist/action-enforcement.js +70 -0
- package/dist/admission-composite.d.ts +67 -0
- package/dist/admission-composite.js +158 -0
- package/dist/admission-enrichment.d.ts +142 -0
- package/dist/admission-enrichment.js +331 -0
- package/dist/admission-hc.d.ts +62 -0
- package/dist/admission-hc.js +83 -0
- package/dist/admission-score.d.ts +148 -0
- package/dist/admission-score.js +237 -0
- package/dist/analysis/analyzer.js +3 -2
- package/dist/analysis/convention-detector.d.ts +85 -2
- package/dist/analysis/convention-detector.js +375 -70
- package/dist/analysis/diff-analyzer.d.ts +33 -0
- package/dist/analysis/diff-analyzer.js +122 -0
- package/dist/analysis/hotspot-analyzer.js +3 -1
- package/dist/analysis/index.d.ts +2 -1
- package/dist/analysis/index.js +2 -1
- package/dist/artifacts/index.d.ts +65 -0
- package/dist/artifacts/index.js +142 -0
- package/dist/backlog-adapter.d.ts +121 -0
- package/dist/backlog-adapter.js +438 -0
- package/dist/calibration.d.ts +43 -0
- package/dist/calibration.js +76 -0
- package/dist/cli/commands/agents.d.ts +24 -0
- package/dist/cli/commands/agents.js +66 -1
- package/dist/cli/commands/git-remote.d.ts +49 -0
- package/dist/cli/commands/git-remote.js +91 -0
- package/dist/cli/commands/health.d.ts +4 -0
- package/dist/cli/commands/health.js +13 -1
- package/dist/cli/commands/init.d.ts +26 -0
- package/dist/cli/commands/init.js +164 -22
- package/dist/cli/commands/mcp-setup.d.ts +31 -0
- package/dist/cli/commands/mcp-setup.js +78 -8
- package/dist/cli/formatters/table.js +15 -2
- package/dist/cli/index.d.ts +14 -1
- package/dist/cli/index.js +81 -20
- package/dist/cli/versions.d.ts +57 -0
- package/dist/cli/versions.js +128 -0
- package/dist/code-area-classifier.d.ts +21 -0
- package/dist/code-area-classifier.js +48 -0
- package/dist/config.d.ts +33 -1
- package/dist/config.js +78 -8
- package/dist/cycle-utils.d.ts +51 -0
- package/dist/cycle-utils.js +77 -0
- package/dist/database/adapters/external.d.ts +24 -0
- package/dist/database/adapters/external.js +80 -0
- package/dist/database/adapters/neon.d.ts +41 -0
- package/dist/database/adapters/neon.js +98 -0
- package/dist/database/adapters/pg-snapshot-restore.d.ts +28 -0
- package/dist/database/adapters/pg-snapshot-restore.js +68 -0
- package/dist/database/adapters/sqlite-copy.d.ts +32 -0
- package/dist/database/adapters/sqlite-copy.js +145 -0
- package/dist/database/connection-injection.d.ts +35 -0
- package/dist/database/connection-injection.js +93 -0
- package/dist/database/index.d.ts +12 -0
- package/dist/database/index.js +23 -0
- package/dist/database/registry.d.ts +13 -0
- package/dist/database/registry.js +27 -0
- package/dist/database/topology.d.ts +52 -0
- package/dist/database/topology.js +44 -0
- package/dist/database/types.d.ts +89 -0
- package/dist/database/types.js +26 -0
- package/dist/defaults.d.ts +5 -0
- package/dist/defaults.js +5 -0
- package/dist/design-authority.d.ts +40 -0
- package/dist/design-authority.js +71 -0
- package/dist/design-lookahead.d.ts +64 -0
- package/dist/design-lookahead.js +86 -0
- package/dist/design-quality-trend.d.ts +87 -0
- package/dist/design-quality-trend.js +190 -0
- package/dist/design-system-context.d.ts +46 -0
- package/dist/design-system-context.js +80 -0
- package/dist/design-system-correction-loop.d.ts +64 -0
- package/dist/design-system-correction-loop.js +128 -0
- package/dist/design-system-metrics.d.ts +61 -0
- package/dist/design-system-metrics.js +104 -0
- package/dist/design-system-stewardship.d.ts +22 -0
- package/dist/design-system-stewardship.js +85 -0
- package/dist/design-system-validation.d.ts +37 -0
- package/dist/design-system-validation.js +88 -0
- package/dist/dispatch/index.d.ts +4 -0
- package/dist/dispatch/index.js +4 -0
- package/dist/dispatch/merge-gate.d.ts +46 -0
- package/dist/dispatch/merge-gate.js +90 -0
- package/dist/dispatch/requeue.d.ts +57 -0
- package/dist/dispatch/requeue.js +131 -0
- package/dist/dispatch/worker-pool.d.ts +62 -0
- package/dist/dispatch/worker-pool.js +60 -0
- package/dist/execute.d.ts +40 -0
- package/dist/execute.js +295 -30
- package/dist/fix-ci.js +40 -3
- package/dist/fix-review.d.ts +66 -0
- package/dist/fix-review.js +448 -0
- package/dist/harness/adapters/claude-code.d.ts +29 -0
- package/dist/harness/adapters/claude-code.js +191 -0
- package/dist/harness/adapters/codex.d.ts +25 -0
- package/dist/harness/adapters/codex.js +61 -0
- package/dist/harness/independence.d.ts +51 -0
- package/dist/harness/independence.js +67 -0
- package/dist/harness/index.d.ts +14 -0
- package/dist/harness/index.js +20 -0
- package/dist/harness/registry.d.ts +17 -0
- package/dist/harness/registry.js +31 -0
- package/dist/harness/types.d.ts +123 -0
- package/dist/harness/types.js +8 -0
- package/dist/harness/version-probe.d.ts +14 -0
- package/dist/harness/version-probe.js +123 -0
- package/dist/index.d.ts +39 -5
- package/dist/index.js +48 -3
- package/dist/models/classifier.d.ts +76 -0
- package/dist/models/classifier.js +221 -0
- package/dist/models/index.d.ts +3 -0
- package/dist/models/index.js +3 -0
- package/dist/models/registry.d.ts +97 -0
- package/dist/models/registry.js +173 -0
- package/dist/pillar-breakdown.d.ts +63 -0
- package/dist/pillar-breakdown.js +153 -0
- package/dist/pipeline-cycle-detector.d.ts +70 -0
- package/dist/pipeline-cycle-detector.js +111 -0
- package/dist/priority.d.ts +7 -76
- package/dist/priority.js +18 -5
- package/dist/review-meta.d.ts +65 -0
- package/dist/review-meta.js +149 -0
- package/dist/review.d.ts +35 -0
- package/dist/review.js +84 -0
- package/dist/runners/claude-code-sdk.d.ts +31 -0
- package/dist/runners/claude-code-sdk.js +238 -0
- package/dist/runners/claude-code.d.ts +3 -0
- package/dist/runners/claude-code.js +319 -73
- package/dist/runners/codex.js +4 -1
- package/dist/runners/copilot.js +4 -1
- package/dist/runners/cursor.js +4 -1
- package/dist/runners/git-utils.d.ts +81 -0
- package/dist/runners/git-utils.js +201 -0
- package/dist/runners/index.d.ts +5 -1
- package/dist/runners/index.js +4 -0
- package/dist/runners/review-agent.d.ts +67 -0
- package/dist/runners/review-agent.js +350 -0
- package/dist/runners/runner-registry.js +10 -0
- package/dist/runners/sdk-review-runner.d.ts +65 -0
- package/dist/runners/sdk-review-runner.js +185 -0
- package/dist/runners/security-triage.d.ts +20 -4
- package/dist/runners/security-triage.js +42 -14
- package/dist/runners/types.d.ts +25 -0
- package/dist/runtime/attestations.d.ts +274 -0
- package/dist/runtime/attestations.js +460 -0
- package/dist/runtime/git-env.d.ts +53 -0
- package/dist/runtime/git-env.js +60 -0
- package/dist/runtime/index.d.ts +7 -0
- package/dist/runtime/index.js +7 -0
- package/dist/runtime/parallelism-flag.d.ts +10 -0
- package/dist/runtime/parallelism-flag.js +18 -0
- package/dist/runtime/port-allocator.d.ts +21 -0
- package/dist/runtime/port-allocator.js +66 -0
- package/dist/runtime/worktree-pool.d.ts +86 -0
- package/dist/runtime/worktree-pool.js +204 -0
- package/dist/runtime/worktree.d.ts +25 -0
- package/dist/runtime/worktree.js +111 -0
- package/dist/sa-scoring/auto-calibrate.d.ts +69 -0
- package/dist/sa-scoring/auto-calibrate.js +107 -0
- package/dist/sa-scoring/c1-sa2-computable.d.ts +42 -0
- package/dist/sa-scoring/c1-sa2-computable.js +59 -0
- package/dist/sa-scoring/composite.d.ts +107 -0
- package/dist/sa-scoring/composite.js +139 -0
- package/dist/sa-scoring/depparse-client.d.ts +79 -0
- package/dist/sa-scoring/depparse-client.js +187 -0
- package/dist/sa-scoring/did-compiler.d.ts +122 -0
- package/dist/sa-scoring/did-compiler.js +286 -0
- package/dist/sa-scoring/drift-monitor.d.ts +84 -0
- package/dist/sa-scoring/drift-monitor.js +186 -0
- package/dist/sa-scoring/exemplar-bank.d.ts +78 -0
- package/dist/sa-scoring/exemplar-bank.js +154 -0
- package/dist/sa-scoring/feedback-store.d.ts +100 -0
- package/dist/sa-scoring/feedback-store.js +156 -0
- package/dist/sa-scoring/index.d.ts +71 -0
- package/dist/sa-scoring/index.js +158 -0
- package/dist/sa-scoring/layer1-deterministic.d.ts +115 -0
- package/dist/sa-scoring/layer1-deterministic.js +298 -0
- package/dist/sa-scoring/layer2-structural.d.ts +71 -0
- package/dist/sa-scoring/layer2-structural.js +151 -0
- package/dist/sa-scoring/layer3-llm.d.ts +86 -0
- package/dist/sa-scoring/layer3-llm.js +282 -0
- package/dist/sa-scoring/rescore-orchestrator.d.ts +52 -0
- package/dist/sa-scoring/rescore-orchestrator.js +47 -0
- package/dist/scheduling/burn-down.d.ts +27 -0
- package/dist/scheduling/burn-down.js +43 -0
- package/dist/scheduling/calibration.d.ts +42 -0
- package/dist/scheduling/calibration.js +150 -0
- package/dist/scheduling/index.d.ts +8 -0
- package/dist/scheduling/index.js +8 -0
- package/dist/scheduling/ledger.d.ts +59 -0
- package/dist/scheduling/ledger.js +216 -0
- package/dist/scheduling/off-peak.d.ts +27 -0
- package/dist/scheduling/off-peak.js +112 -0
- package/dist/scheduling/schedule-decision.d.ts +39 -0
- package/dist/scheduling/schedule-decision.js +89 -0
- package/dist/scheduling/tier-analysis.d.ts +47 -0
- package/dist/scheduling/tier-analysis.js +81 -0
- package/dist/scheduling/types.d.ts +140 -0
- package/dist/scheduling/types.js +11 -0
- package/dist/shared.d.ts +13 -0
- package/dist/shared.js +32 -0
- package/dist/state/index.d.ts +1 -1
- package/dist/state/schema.d.ts +6 -1
- package/dist/state/schema.js +276 -1
- package/dist/state/store.d.ts +71 -1
- package/dist/state/store.js +464 -7
- package/dist/state/types.d.ts +174 -0
- package/dist/types.d.ts +1 -1
- package/dist/validate-agent-output.js +4 -1
- package/dist/watch.js +6 -0
- package/dist/workflow-patterns/artifact-writer.d.ts +16 -0
- package/dist/workflow-patterns/artifact-writer.js +34 -0
- package/dist/workflow-patterns/classifiers.d.ts +10 -0
- package/dist/workflow-patterns/classifiers.js +72 -0
- package/dist/workflow-patterns/detector.d.ts +27 -0
- package/dist/workflow-patterns/detector.js +186 -0
- package/dist/workflow-patterns/index.d.ts +8 -0
- package/dist/workflow-patterns/index.js +7 -0
- package/dist/workflow-patterns/proposal-generator.d.ts +15 -0
- package/dist/workflow-patterns/proposal-generator.js +183 -0
- package/dist/workflow-patterns/telemetry-ingest.d.ts +27 -0
- package/dist/workflow-patterns/telemetry-ingest.js +103 -0
- package/dist/workflow-patterns/types.d.ts +61 -0
- package/dist/workflow-patterns/types.js +11 -0
- package/package.json +2 -2
|
@@ -0,0 +1,331 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bridge between stateless admission scoring and the stateful orchestrator
|
|
3
|
+
* (RFC-0008 Addendum A §A.2 – §A.5).
|
|
4
|
+
*
|
|
5
|
+
* `enrichAdmissionInput()` reads from the orchestrator's state store and
|
|
6
|
+
* resolved resources to populate the RFC-0008 context fields on
|
|
7
|
+
* `AdmissionInput`, then `computeDesignSystemReadiness()` produces the
|
|
8
|
+
* Eρ₄ scalar that feeds the admission composite in §A.6.
|
|
9
|
+
*
|
|
10
|
+
* Scope for AISDLC-43: implement C2 (Eρ₄) only. C3/C4/C5 are populated
|
|
11
|
+
* by later tasks (AISDLC-44/45/46).
|
|
12
|
+
*/
|
|
13
|
+
import { checkHasFrontendComponents } from './code-area-classifier.js';
|
|
14
|
+
import { checkDesignAuthority } from './design-authority.js';
|
|
15
|
+
/**
|
|
16
|
+
* Minimum data points required before `code_area_metrics` is trusted
|
|
17
|
+
* enough to drive defect-risk penalties (RFC-0008 §7.4 Open Question 4).
|
|
18
|
+
*/
|
|
19
|
+
export const CODE_AREA_METRICS_MIN_DATA_POINTS = 10;
|
|
20
|
+
/** Default window (ms) for `getCodeAreaMetrics` lookups — 90 days. */
|
|
21
|
+
const DEFAULT_METRICS_WINDOW_MS = 90 * 24 * 60 * 60 * 1000;
|
|
22
|
+
/**
|
|
23
|
+
* Populate `designSystemContext` on the admission input using the
|
|
24
|
+
* resolved DSB and state store. Returns the input unchanged when no DSB
|
|
25
|
+
* is available (preDesignSystem phase — caller falls through to the
|
|
26
|
+
* stateless path).
|
|
27
|
+
*/
|
|
28
|
+
export function enrichAdmissionInput(input, ctx) {
|
|
29
|
+
const binding = ctx.designSystemBinding;
|
|
30
|
+
const codeAreaQuality = ctx.codeArea
|
|
31
|
+
? buildCodeAreaQuality(ctx.codeArea, ctx.stateStore, ctx.now)
|
|
32
|
+
: undefined;
|
|
33
|
+
const autonomyContext = buildAutonomyContext(ctx);
|
|
34
|
+
const designAuthoritySignal = buildDesignAuthoritySignal(input, ctx);
|
|
35
|
+
if (!binding) {
|
|
36
|
+
const next = { ...input };
|
|
37
|
+
// When ctx.codeArea is set but buildCodeAreaQuality returns undefined
|
|
38
|
+
// (insufficient data), explicitly clear any stale value that may have
|
|
39
|
+
// been carried over from input — otherwise the spread above preserves
|
|
40
|
+
// it and drives a bogus defect-risk penalty.
|
|
41
|
+
if (ctx.codeArea)
|
|
42
|
+
next.codeAreaQuality = codeAreaQuality;
|
|
43
|
+
if (autonomyContext)
|
|
44
|
+
next.autonomyContext = autonomyContext;
|
|
45
|
+
if (designAuthoritySignal)
|
|
46
|
+
next.designAuthoritySignal = designAuthoritySignal;
|
|
47
|
+
return next;
|
|
48
|
+
}
|
|
49
|
+
const catalogCoverageRaw = binding.status?.catalogHealth?.coveragePercent;
|
|
50
|
+
const tokenComplianceRaw = binding.status?.tokenCompliance?.currentCoverage;
|
|
51
|
+
const catalogCoverage = normalizeCoverage(catalogCoverageRaw);
|
|
52
|
+
const tokenCompliance = normalizeCoverage(tokenComplianceRaw);
|
|
53
|
+
const baselineCoverage = ctx.stateStore
|
|
54
|
+
? computeBaselineCoverage(ctx.stateStore, binding.metadata.name)
|
|
55
|
+
: 0;
|
|
56
|
+
const ageDays = computeDsbAgeDays(ctx.dsbAdoptedAt, ctx.now);
|
|
57
|
+
const phase = detectLifecyclePhase(binding, catalogCoverage, ageDays);
|
|
58
|
+
const context = {
|
|
59
|
+
catalogCoverage,
|
|
60
|
+
tokenCompliance,
|
|
61
|
+
inBootstrapPhase: phase === 'catalogBootstrap',
|
|
62
|
+
baselineCoverage,
|
|
63
|
+
catalogGaps: ctx.catalogGaps ?? [],
|
|
64
|
+
};
|
|
65
|
+
return {
|
|
66
|
+
...input,
|
|
67
|
+
designSystemContext: context,
|
|
68
|
+
// When ctx.codeArea is set we always write codeAreaQuality — either
|
|
69
|
+
// the computed value or `undefined` — so stale input.codeAreaQuality
|
|
70
|
+
// can't silently drive a penalty under fresh enrichment context.
|
|
71
|
+
...(ctx.codeArea ? { codeAreaQuality } : {}),
|
|
72
|
+
...(autonomyContext ? { autonomyContext } : {}),
|
|
73
|
+
...(designAuthoritySignal ? { designAuthoritySignal } : {}),
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Read code-area metrics within the 90-day window and project them into
|
|
78
|
+
* the `CodeAreaQuality` shape. Returns undefined when the metric row is
|
|
79
|
+
* missing or has fewer than `CODE_AREA_METRICS_MIN_DATA_POINTS` samples —
|
|
80
|
+
* downstream defect-risk consumers treat "absent" as 0 penalty.
|
|
81
|
+
*/
|
|
82
|
+
function buildCodeAreaQuality(codeArea, store, now) {
|
|
83
|
+
if (!store) {
|
|
84
|
+
// No state → fall back to heuristic classification only.
|
|
85
|
+
return { hasFrontendComponents: checkHasFrontendComponents(codeArea) };
|
|
86
|
+
}
|
|
87
|
+
const windowStart = new Date((now ?? (() => Date.now()))() - DEFAULT_METRICS_WINDOW_MS).toISOString();
|
|
88
|
+
const metrics = store.getCodeAreaMetrics(codeArea, { since: windowStart });
|
|
89
|
+
if (!metrics || (metrics.dataPointCount ?? 0) < CODE_AREA_METRICS_MIN_DATA_POINTS) {
|
|
90
|
+
return undefined;
|
|
91
|
+
}
|
|
92
|
+
const designQuality = parseDesignQuality(metrics.designMetricsJson);
|
|
93
|
+
return {
|
|
94
|
+
defectDensity: metrics.defectDensity,
|
|
95
|
+
churnRate: metrics.churnRate,
|
|
96
|
+
prRejectionRate: metrics.prRejectionRate,
|
|
97
|
+
hasFrontendComponents: metrics.hasFrontendComponents ?? false,
|
|
98
|
+
...(designQuality ? { designQuality } : {}),
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
function parseDesignQuality(json) {
|
|
102
|
+
if (!json)
|
|
103
|
+
return undefined;
|
|
104
|
+
try {
|
|
105
|
+
const parsed = JSON.parse(json);
|
|
106
|
+
if (parsed.designCIPassRate === undefined &&
|
|
107
|
+
parsed.designReviewRejectionRate === undefined &&
|
|
108
|
+
parsed.usabilitySimPassRate === undefined) {
|
|
109
|
+
return undefined;
|
|
110
|
+
}
|
|
111
|
+
return parsed;
|
|
112
|
+
}
|
|
113
|
+
catch {
|
|
114
|
+
return undefined;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Compute the C3 defect-risk factor per §A.5. Returns 0 when
|
|
119
|
+
* `codeAreaQuality` is absent (insufficient data → no penalty).
|
|
120
|
+
*
|
|
121
|
+
* !hasFrontendComponents → 0.5×dd + 0.3×churn + 0.2×prRej
|
|
122
|
+
* hasFrontendComponents
|
|
123
|
+
* no designQuality → same as pure code (no blend target)
|
|
124
|
+
* with designQuality → 0.7 × code + 0.3 × design
|
|
125
|
+
* where design = 0.4×(1-ciPass)
|
|
126
|
+
* + 0.4×reviewRej
|
|
127
|
+
* + 0.2×(1-usabPass)
|
|
128
|
+
*
|
|
129
|
+
* Final value is clamped to [0, 0.5].
|
|
130
|
+
*/
|
|
131
|
+
export function computeDefectRiskFactor(quality) {
|
|
132
|
+
if (!quality)
|
|
133
|
+
return 0;
|
|
134
|
+
const code = 0.5 * (quality.defectDensity ?? 0) +
|
|
135
|
+
0.3 * (quality.churnRate ?? 0) +
|
|
136
|
+
0.2 * (quality.prRejectionRate ?? 0);
|
|
137
|
+
if (!quality.hasFrontendComponents || !quality.designQuality) {
|
|
138
|
+
return clamp(code, 0, 0.5);
|
|
139
|
+
}
|
|
140
|
+
const dq = quality.designQuality;
|
|
141
|
+
const ciPass = dq.designCIPassRate ?? 1;
|
|
142
|
+
const reviewRej = dq.designReviewRejectionRate ?? 0;
|
|
143
|
+
const usabPass = dq.usabilitySimPassRate ?? 1;
|
|
144
|
+
const design = 0.4 * (1 - ciPass) + 0.4 * reviewRej + 0.2 * (1 - usabPass);
|
|
145
|
+
const blended = 0.7 * code + 0.3 * design;
|
|
146
|
+
return clamp(blended, 0, 0.5);
|
|
147
|
+
}
|
|
148
|
+
function clamp(value, min, max) {
|
|
149
|
+
return Math.min(max, Math.max(min, value));
|
|
150
|
+
}
|
|
151
|
+
// ── C4 Autonomy Factor ─────────────────────────────────────────────────
|
|
152
|
+
/**
|
|
153
|
+
* Map task complexity to the required autonomy level per §A.4:
|
|
154
|
+
* complexity ≤ 3 → level 1
|
|
155
|
+
* complexity ≤ 6 → level 2
|
|
156
|
+
* else → level 3
|
|
157
|
+
*/
|
|
158
|
+
export function complexityToAutonomyLevel(complexity) {
|
|
159
|
+
if (complexity <= 3)
|
|
160
|
+
return 1;
|
|
161
|
+
if (complexity <= 6)
|
|
162
|
+
return 2;
|
|
163
|
+
return 3;
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Compute the C4 autonomy factor per §A.5:
|
|
167
|
+
* gap = requiredLevel - currentEarnedLevel
|
|
168
|
+
* gap > 0 → max(0.1, 1.0 - gap × 0.4)
|
|
169
|
+
* gap ≤ 0 → 1.0
|
|
170
|
+
*/
|
|
171
|
+
export function computeAutonomyFactor(ctx) {
|
|
172
|
+
if (!ctx)
|
|
173
|
+
return 1.0;
|
|
174
|
+
const gap = ctx.requiredLevel - ctx.currentEarnedLevel;
|
|
175
|
+
if (gap <= 0)
|
|
176
|
+
return 1.0;
|
|
177
|
+
return Math.max(0.1, 1.0 - gap * 0.4);
|
|
178
|
+
}
|
|
179
|
+
function buildAutonomyContext(ctx) {
|
|
180
|
+
if (!ctx.autonomyPolicy)
|
|
181
|
+
return undefined;
|
|
182
|
+
const agents = ctx.autonomyPolicy.status?.agents ?? [];
|
|
183
|
+
if (agents.length === 0)
|
|
184
|
+
return undefined;
|
|
185
|
+
const selected = ctx.agentName
|
|
186
|
+
? agents.find((a) => a.name === ctx.agentName)
|
|
187
|
+
: pickMostPermissiveAgent(agents);
|
|
188
|
+
if (!selected)
|
|
189
|
+
return undefined;
|
|
190
|
+
const currentEarnedLevel = selected.currentLevel;
|
|
191
|
+
const requiredLevel = ctx.complexity !== undefined ? complexityToAutonomyLevel(ctx.complexity) : currentEarnedLevel;
|
|
192
|
+
return { currentEarnedLevel, requiredLevel };
|
|
193
|
+
}
|
|
194
|
+
function pickMostPermissiveAgent(agents) {
|
|
195
|
+
return agents.reduce((best, a) => (a.currentLevel > best.currentLevel ? a : best), agents[0]);
|
|
196
|
+
}
|
|
197
|
+
// ── C5 Design Authority Signal + HC_design ─────────────────────────────
|
|
198
|
+
/** Base weights per signal type (§A.5) before compliance modulation. */
|
|
199
|
+
const DESIGN_AUTHORITY_BASE_WEIGHT = Object.freeze({
|
|
200
|
+
'advances-design-coherence': 0.6,
|
|
201
|
+
'fills-catalog-gap': 0.6,
|
|
202
|
+
'fragments-component-catalog': -0.4,
|
|
203
|
+
'misaligned-with-brand': -0.4,
|
|
204
|
+
unspecified: 0.3,
|
|
205
|
+
});
|
|
206
|
+
/**
|
|
207
|
+
* Compute the C5 design-authority weight per §A.5.
|
|
208
|
+
*
|
|
209
|
+
* non-authority → 0.0
|
|
210
|
+
* authority + positive → +0.6 × modulation
|
|
211
|
+
* authority + negative → -0.4 × modulation
|
|
212
|
+
* authority + no type → +0.3 × modulation
|
|
213
|
+
*
|
|
214
|
+
* where `modulation = 1.2 - areaComplianceScore` when the score is
|
|
215
|
+
* supplied, else `1.0` (unmodulated base weight).
|
|
216
|
+
*/
|
|
217
|
+
export function computeDesignAuthorityWeight(signal) {
|
|
218
|
+
if (!signal || !signal.isDesignAuthority)
|
|
219
|
+
return 0;
|
|
220
|
+
const signalType = signal.signalType ?? 'unspecified';
|
|
221
|
+
const base = DESIGN_AUTHORITY_BASE_WEIGHT[signalType];
|
|
222
|
+
const modulation = signal.areaComplianceScore !== undefined ? 1.2 - signal.areaComplianceScore : 1;
|
|
223
|
+
return base * modulation;
|
|
224
|
+
}
|
|
225
|
+
function buildDesignAuthoritySignal(input, ctx) {
|
|
226
|
+
if (!ctx.designSystemBinding)
|
|
227
|
+
return undefined;
|
|
228
|
+
const { isDesignAuthority, signalType } = checkDesignAuthority({
|
|
229
|
+
authorLogin: input.authorLogin,
|
|
230
|
+
commenterLogins: input.commenterLogins,
|
|
231
|
+
labels: input.labels,
|
|
232
|
+
}, ctx.designSystemBinding);
|
|
233
|
+
if (!isDesignAuthority)
|
|
234
|
+
return { isDesignAuthority: false };
|
|
235
|
+
return {
|
|
236
|
+
isDesignAuthority: true,
|
|
237
|
+
signalType,
|
|
238
|
+
...(ctx.areaComplianceScore !== undefined
|
|
239
|
+
? { areaComplianceScore: ctx.areaComplianceScore }
|
|
240
|
+
: {}),
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* Compute the C2 Eρ₄ design-system readiness scalar in [0, 1] per §A.5.
|
|
245
|
+
*
|
|
246
|
+
* preDesignSystem: 1.0 (no DSB → no penalty)
|
|
247
|
+
* catalogBootstrap: max(0.3, 0.4×cat + 0.3×tok + 0.3×baseline)
|
|
248
|
+
* postDesignSystem: 0.4×cat + 0.3×tok + 0.3×baseline
|
|
249
|
+
*/
|
|
250
|
+
export function computeDesignSystemReadiness(ctx) {
|
|
251
|
+
const binding = ctx.designSystemBinding;
|
|
252
|
+
if (!binding)
|
|
253
|
+
return 1.0;
|
|
254
|
+
const catalogCoverage = normalizeCoverage(binding.status?.catalogHealth?.coveragePercent);
|
|
255
|
+
const tokenCompliance = normalizeCoverage(binding.status?.tokenCompliance?.currentCoverage);
|
|
256
|
+
const baselineCoverage = ctx.stateStore
|
|
257
|
+
? computeBaselineCoverage(ctx.stateStore, binding.metadata.name)
|
|
258
|
+
: 0;
|
|
259
|
+
const ageDays = computeDsbAgeDays(ctx.dsbAdoptedAt, ctx.now);
|
|
260
|
+
const phase = detectLifecyclePhase(binding, catalogCoverage, ageDays);
|
|
261
|
+
const computed = 0.4 * catalogCoverage + 0.3 * tokenCompliance + 0.3 * baselineCoverage;
|
|
262
|
+
if (phase === 'catalogBootstrap')
|
|
263
|
+
return Math.max(0.3, computed);
|
|
264
|
+
return computed;
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* Compute the C2 Eρ₄ scalar directly from the DesignSystemContext
|
|
268
|
+
* already populated on an `AdmissionInput` (no DSB/state lookups).
|
|
269
|
+
*
|
|
270
|
+
* undefined (preDesignSystem) → 1.0
|
|
271
|
+
* inBootstrapPhase → max(0.3, computed)
|
|
272
|
+
* else → computed
|
|
273
|
+
*
|
|
274
|
+
* Used by the admission composite (§A.6) to avoid re-reading the state
|
|
275
|
+
* store on every score call.
|
|
276
|
+
*/
|
|
277
|
+
export function computeReadinessFromDesignSystemContext(context) {
|
|
278
|
+
if (!context)
|
|
279
|
+
return 1.0;
|
|
280
|
+
const catalogCoverage = normalizeCoverage(context.catalogCoverage);
|
|
281
|
+
const tokenCompliance = normalizeCoverage(context.tokenCompliance);
|
|
282
|
+
const baselineCoverage = normalizeCoverage(context.baselineCoverage);
|
|
283
|
+
const computed = 0.4 * catalogCoverage + 0.3 * tokenCompliance + 0.3 * baselineCoverage;
|
|
284
|
+
if (context.inBootstrapPhase)
|
|
285
|
+
return Math.max(0.3, computed);
|
|
286
|
+
return computed;
|
|
287
|
+
}
|
|
288
|
+
export function detectLifecyclePhase(binding, normalizedCatalogCoverage, ageDays) {
|
|
289
|
+
if (!binding)
|
|
290
|
+
return 'preDesignSystem';
|
|
291
|
+
if (normalizedCatalogCoverage < 0.2 && ageDays < 90)
|
|
292
|
+
return 'catalogBootstrap';
|
|
293
|
+
return 'postDesignSystem';
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
296
|
+
* Days since the DSB was adopted. Returns 0 when no adoption timestamp
|
|
297
|
+
* is supplied — the conservative default (treats DSB as brand-new and
|
|
298
|
+
* favours the bootstrap floor).
|
|
299
|
+
*/
|
|
300
|
+
export function computeDsbAgeDays(adoptedAt, now) {
|
|
301
|
+
if (!adoptedAt)
|
|
302
|
+
return 0;
|
|
303
|
+
const adoptedMs = Date.parse(adoptedAt);
|
|
304
|
+
if (Number.isNaN(adoptedMs))
|
|
305
|
+
return 0;
|
|
306
|
+
const nowMs = (now ?? (() => Date.now()))();
|
|
307
|
+
const diffMs = Math.max(0, nowMs - adoptedMs);
|
|
308
|
+
return diffMs / (1000 * 60 * 60 * 24);
|
|
309
|
+
}
|
|
310
|
+
/**
|
|
311
|
+
* Fraction of the UI under visual-regression monitoring for this binding,
|
|
312
|
+
* derived from approved baselines in `visual_regression_results`.
|
|
313
|
+
*
|
|
314
|
+
* Definition (§A.5 proxy): `approvedBaselines / totalBaselines`. Returns
|
|
315
|
+
* 0 when no history exists (bootstrap protection: avoids over-crediting
|
|
316
|
+
* readiness when the monitor hasn't run yet).
|
|
317
|
+
*/
|
|
318
|
+
export function computeBaselineCoverage(store, bindingName) {
|
|
319
|
+
const history = store.getVisualRegressionResults(bindingName, 1000);
|
|
320
|
+
if (history.length === 0)
|
|
321
|
+
return 0;
|
|
322
|
+
const approved = history.filter((r) => Boolean(r.approved)).length;
|
|
323
|
+
return approved / history.length;
|
|
324
|
+
}
|
|
325
|
+
function normalizeCoverage(value) {
|
|
326
|
+
if (value === undefined || Number.isNaN(value))
|
|
327
|
+
return 0;
|
|
328
|
+
const clamped = value > 1 ? value / 100 : value;
|
|
329
|
+
return Math.min(1, Math.max(0, clamped));
|
|
330
|
+
}
|
|
331
|
+
//# sourceMappingURL=admission-enrichment.js.map
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Admission-specific Human Curve composite (RFC-0008 §A.6, Amendment 4).
|
|
3
|
+
*
|
|
4
|
+
* The admission HC differs from the legacy PPA HC in two ways:
|
|
5
|
+
* 1. Four terms instead of three — HC_design enters at 0.10 weight.
|
|
6
|
+
* 2. Weights are (0.2, 0.45, 0.25, 0.10) rather than (0.5, 0.3, 0.2).
|
|
7
|
+
*
|
|
8
|
+
* HC_design flows through tanh alongside the other three components;
|
|
9
|
+
* it is NOT a direct soul-alignment modifier (Amendment 5 correction
|
|
10
|
+
* to the v3 draft).
|
|
11
|
+
*
|
|
12
|
+
* The `override` bypass on `PriorityInput` is still position-1: this
|
|
13
|
+
* module never runs when an override is active — the admission
|
|
14
|
+
* composite (AISDLC-48) short-circuits on override before calling
|
|
15
|
+
* `computeAdmissionHumanCurve`.
|
|
16
|
+
*/
|
|
17
|
+
import type { AdmissionInput, DesignAuthoritySignal } from './admission-score.js';
|
|
18
|
+
/**
|
|
19
|
+
* Fixed §A.6 weights. Exposed for validation and for downstream callers
|
|
20
|
+
* that need to introspect the HC decomposition.
|
|
21
|
+
*/
|
|
22
|
+
export declare const HC_WEIGHTS: Readonly<{
|
|
23
|
+
explicit: 0.2;
|
|
24
|
+
consensus: 0.45;
|
|
25
|
+
decision: 0.25;
|
|
26
|
+
design: 0.1;
|
|
27
|
+
}>;
|
|
28
|
+
/** Sum of HC_WEIGHTS — must equal 1.0 exactly (AC #2). */
|
|
29
|
+
export declare const HC_WEIGHT_SUM: number;
|
|
30
|
+
export interface AdmissionHumanCurveResult {
|
|
31
|
+
/** Signed explicit-priority signal in [-1, 1]. */
|
|
32
|
+
hcExplicit: number;
|
|
33
|
+
/** Signed consensus signal in [-1, 1]. */
|
|
34
|
+
hcConsensus: number;
|
|
35
|
+
/** Signed meeting-decision signal in [-1, 1] (0 = neutral when absent). */
|
|
36
|
+
hcDecision: number;
|
|
37
|
+
/** Signed design-authority signal in [-1, 1]. */
|
|
38
|
+
hcDesign: number;
|
|
39
|
+
/** Weighted sum before tanh. */
|
|
40
|
+
hcRaw: number;
|
|
41
|
+
/** `tanh(hcRaw)` — the HC value consumed by the admission composite. */
|
|
42
|
+
hcComposite: number;
|
|
43
|
+
}
|
|
44
|
+
export declare function deriveHcExplicit(input: Pick<AdmissionInput, 'labels'>): number;
|
|
45
|
+
export declare function deriveHcConsensus(input: Pick<AdmissionInput, 'reactionCount' | 'authorAssociation'>): number;
|
|
46
|
+
/**
|
|
47
|
+
* HC_decision — meeting-decision signal in [-1, 1].
|
|
48
|
+
*
|
|
49
|
+
* AdmissionInput has no dedicated meeting-decision field. We return
|
|
50
|
+
* neutral (0) by default. Callers that later add a GitHub-comment
|
|
51
|
+
* parser for `/decide approve` / `/decide reject` can plumb it through
|
|
52
|
+
* via an optional AdmissionInput field without breaking this shape.
|
|
53
|
+
*/
|
|
54
|
+
export declare function deriveHcDecision(_input: AdmissionInput): number;
|
|
55
|
+
export declare function deriveHcDesign(signal: DesignAuthoritySignal | undefined): number;
|
|
56
|
+
/**
|
|
57
|
+
* Compute the admission HC composite from an `AdmissionInput`.
|
|
58
|
+
* Returns both the weighted pre-tanh sum and the tanh-compressed value
|
|
59
|
+
* for auditability.
|
|
60
|
+
*/
|
|
61
|
+
export declare function computeAdmissionHumanCurve(input: AdmissionInput): AdmissionHumanCurveResult;
|
|
62
|
+
//# sourceMappingURL=admission-hc.d.ts.map
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Admission-specific Human Curve composite (RFC-0008 §A.6, Amendment 4).
|
|
3
|
+
*
|
|
4
|
+
* The admission HC differs from the legacy PPA HC in two ways:
|
|
5
|
+
* 1. Four terms instead of three — HC_design enters at 0.10 weight.
|
|
6
|
+
* 2. Weights are (0.2, 0.45, 0.25, 0.10) rather than (0.5, 0.3, 0.2).
|
|
7
|
+
*
|
|
8
|
+
* HC_design flows through tanh alongside the other three components;
|
|
9
|
+
* it is NOT a direct soul-alignment modifier (Amendment 5 correction
|
|
10
|
+
* to the v3 draft).
|
|
11
|
+
*
|
|
12
|
+
* The `override` bypass on `PriorityInput` is still position-1: this
|
|
13
|
+
* module never runs when an override is active — the admission
|
|
14
|
+
* composite (AISDLC-48) short-circuits on override before calling
|
|
15
|
+
* `computeAdmissionHumanCurve`.
|
|
16
|
+
*/
|
|
17
|
+
import { computeDesignAuthorityWeight } from './admission-enrichment.js';
|
|
18
|
+
/**
|
|
19
|
+
* Fixed §A.6 weights. Exposed for validation and for downstream callers
|
|
20
|
+
* that need to introspect the HC decomposition.
|
|
21
|
+
*/
|
|
22
|
+
export const HC_WEIGHTS = Object.freeze({
|
|
23
|
+
explicit: 0.2,
|
|
24
|
+
consensus: 0.45,
|
|
25
|
+
decision: 0.25,
|
|
26
|
+
design: 0.1,
|
|
27
|
+
});
|
|
28
|
+
/** Sum of HC_WEIGHTS — must equal 1.0 exactly (AC #2). */
|
|
29
|
+
export const HC_WEIGHT_SUM = HC_WEIGHTS.explicit + HC_WEIGHTS.consensus + HC_WEIGHTS.decision + HC_WEIGHTS.design;
|
|
30
|
+
const TRUSTED_ASSOCIATIONS = new Set(['OWNER', 'MEMBER', 'COLLABORATOR']);
|
|
31
|
+
export function deriveHcExplicit(input) {
|
|
32
|
+
const labels = input.labels;
|
|
33
|
+
if (labels.includes('high') || labels.includes('P0') || labels.includes('critical')) {
|
|
34
|
+
return 1.0;
|
|
35
|
+
}
|
|
36
|
+
if (labels.includes('low') || labels.includes('backlog'))
|
|
37
|
+
return -1.0;
|
|
38
|
+
return 0;
|
|
39
|
+
}
|
|
40
|
+
export function deriveHcConsensus(input) {
|
|
41
|
+
const isTrusted = TRUSTED_ASSOCIATIONS.has(input.authorAssociation ?? 'NONE');
|
|
42
|
+
const reactionConsensus = Math.min(1, input.reactionCount / 5);
|
|
43
|
+
// Trusted authors carry implicit team consensus — floor at 0.5 before centering.
|
|
44
|
+
const base = isTrusted ? Math.max(0.5, reactionConsensus) : reactionConsensus;
|
|
45
|
+
// [0, 1] → [-1, 1]
|
|
46
|
+
return base * 2 - 1;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* HC_decision — meeting-decision signal in [-1, 1].
|
|
50
|
+
*
|
|
51
|
+
* AdmissionInput has no dedicated meeting-decision field. We return
|
|
52
|
+
* neutral (0) by default. Callers that later add a GitHub-comment
|
|
53
|
+
* parser for `/decide approve` / `/decide reject` can plumb it through
|
|
54
|
+
* via an optional AdmissionInput field without breaking this shape.
|
|
55
|
+
*/
|
|
56
|
+
export function deriveHcDecision(_input) {
|
|
57
|
+
return 0;
|
|
58
|
+
}
|
|
59
|
+
export function deriveHcDesign(signal) {
|
|
60
|
+
const raw = computeDesignAuthorityWeight(signal);
|
|
61
|
+
return clamp(raw, -1, 1);
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Compute the admission HC composite from an `AdmissionInput`.
|
|
65
|
+
* Returns both the weighted pre-tanh sum and the tanh-compressed value
|
|
66
|
+
* for auditability.
|
|
67
|
+
*/
|
|
68
|
+
export function computeAdmissionHumanCurve(input) {
|
|
69
|
+
const hcExplicit = deriveHcExplicit(input);
|
|
70
|
+
const hcConsensus = deriveHcConsensus(input);
|
|
71
|
+
const hcDecision = deriveHcDecision(input);
|
|
72
|
+
const hcDesign = deriveHcDesign(input.designAuthoritySignal);
|
|
73
|
+
const hcRaw = HC_WEIGHTS.explicit * hcExplicit +
|
|
74
|
+
HC_WEIGHTS.consensus * hcConsensus +
|
|
75
|
+
HC_WEIGHTS.decision * hcDecision +
|
|
76
|
+
HC_WEIGHTS.design * hcDesign;
|
|
77
|
+
const hcComposite = Math.tanh(hcRaw);
|
|
78
|
+
return { hcExplicit, hcConsensus, hcDecision, hcDesign, hcRaw, hcComposite };
|
|
79
|
+
}
|
|
80
|
+
function clamp(value, min, max) {
|
|
81
|
+
return Math.min(max, Math.max(min, value));
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=admission-hc.js.map
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Issue admission scoring — maps GitHub issue fields to PPA dimensions
|
|
3
|
+
* and determines whether an issue should enter the pipeline.
|
|
4
|
+
*
|
|
5
|
+
* Extracted from dogfood/scripts/ppa-score.ts for reuse across CLI
|
|
6
|
+
* scripts and workflows.
|
|
7
|
+
*/
|
|
8
|
+
import type { PriorityInput, PriorityScore, PriorityConfig } from './priority.js';
|
|
9
|
+
import { type PillarBreakdown } from './pillar-breakdown.js';
|
|
10
|
+
/**
|
|
11
|
+
* GitHub author_association values indicating trust level.
|
|
12
|
+
* OWNER/MEMBER/COLLABORATOR = trusted (project team)
|
|
13
|
+
* CONTRIBUTOR = semi-trusted (has had PRs merged)
|
|
14
|
+
* NONE = untrusted (external)
|
|
15
|
+
*/
|
|
16
|
+
export type AuthorAssociation = 'OWNER' | 'MEMBER' | 'COLLABORATOR' | 'CONTRIBUTOR' | 'FIRST_TIMER' | 'FIRST_TIME_CONTRIBUTOR' | 'NONE';
|
|
17
|
+
export interface AdmissionInput {
|
|
18
|
+
issueNumber: number;
|
|
19
|
+
title: string;
|
|
20
|
+
body: string;
|
|
21
|
+
labels: string[];
|
|
22
|
+
/** Total thumbsUp + heart reactions. */
|
|
23
|
+
reactionCount: number;
|
|
24
|
+
/** Number of human comments. */
|
|
25
|
+
commentCount: number;
|
|
26
|
+
/** ISO timestamp of issue creation. */
|
|
27
|
+
createdAt: string;
|
|
28
|
+
/** GitHub author_association — determines trust-based signal boosting. */
|
|
29
|
+
authorAssociation?: AuthorAssociation;
|
|
30
|
+
/** GitHub login of the issue author (used by C5 principal match). */
|
|
31
|
+
authorLogin?: string;
|
|
32
|
+
/** GitHub logins of anyone who commented on the issue (C5 principal match). */
|
|
33
|
+
commenterLogins?: string[];
|
|
34
|
+
/** C2 Eρ₄ inputs — populated by enrichAdmissionInput() (AISDLC-43). */
|
|
35
|
+
designSystemContext?: DesignSystemContext;
|
|
36
|
+
/** C4 inputs — current earned autonomy vs. required level (AISDLC-45). */
|
|
37
|
+
autonomyContext?: AutonomyContext;
|
|
38
|
+
/** C3 inputs — defect/churn/rejection signals per code area (AISDLC-44). */
|
|
39
|
+
codeAreaQuality?: CodeAreaQuality;
|
|
40
|
+
/** C5 inputs — HC_design signal from design-authority principals (AISDLC-46). */
|
|
41
|
+
designAuthoritySignal?: DesignAuthoritySignal;
|
|
42
|
+
/**
|
|
43
|
+
* Backlog-task signals (RFC-0010 dual-workflow). Populated when the issue comes
|
|
44
|
+
* from a Backlog.md task instead of GitHub. Used to discriminate between tasks
|
|
45
|
+
* that share identical GitHub-style signals (no reactions / no comments / OWNER
|
|
46
|
+
* author) — typical for the internal backlog workflow.
|
|
47
|
+
*/
|
|
48
|
+
backlogContext?: BacklogContext;
|
|
49
|
+
}
|
|
50
|
+
export interface BacklogContext {
|
|
51
|
+
/** Frontmatter `priority` field — operator's stated importance. */
|
|
52
|
+
priority?: 'critical' | 'high' | 'medium' | 'low';
|
|
53
|
+
/** Number of tasks this one is blocked by (frontmatter `dependencies`). */
|
|
54
|
+
dependencyCount?: number;
|
|
55
|
+
/** Number of file/RFC/URL references in the task body. */
|
|
56
|
+
referenceCount?: number;
|
|
57
|
+
/** Number of acceptance criteria — proxy for scope. */
|
|
58
|
+
acceptanceCriteriaCount?: number;
|
|
59
|
+
/** Frontmatter `status` value (e.g. "To Do", "Draft", "In Progress", "Done"). */
|
|
60
|
+
status?: string;
|
|
61
|
+
}
|
|
62
|
+
export interface DesignSystemContext {
|
|
63
|
+
/** Catalog coverage percent (0–100) from DSB.status.catalogHealth. */
|
|
64
|
+
catalogCoverage?: number;
|
|
65
|
+
/** Token compliance percent (0–100) from DSB.status.tokenCompliance. */
|
|
66
|
+
tokenCompliance?: number;
|
|
67
|
+
/** True when DSB is young or catalog coverage is below the bootstrap floor. */
|
|
68
|
+
inBootstrapPhase?: boolean;
|
|
69
|
+
/** Baseline coverage from visual_regression_results before DSB adoption. */
|
|
70
|
+
baselineCoverage?: number;
|
|
71
|
+
/** Component/token gaps preventing the issue from being built catalog-first. */
|
|
72
|
+
catalogGaps?: string[];
|
|
73
|
+
}
|
|
74
|
+
export interface AutonomyContext {
|
|
75
|
+
/** The AutonomyPolicy-issued earned level for the current agent (0–3). */
|
|
76
|
+
currentEarnedLevel: number;
|
|
77
|
+
/** Level required by the issue's complexity band (≤3→1, ≤6→2, else→3). */
|
|
78
|
+
requiredLevel: number;
|
|
79
|
+
}
|
|
80
|
+
export interface DesignQualityMetrics {
|
|
81
|
+
/** Fraction of design CI checks passing in the window (0–1). */
|
|
82
|
+
designCIPassRate?: number;
|
|
83
|
+
/** Fraction of PRs in the area rejected on design grounds (0–1). */
|
|
84
|
+
designReviewRejectionRate?: number;
|
|
85
|
+
/** Fraction of usability-sim tasks completed successfully (0–1). */
|
|
86
|
+
usabilitySimPassRate?: number;
|
|
87
|
+
}
|
|
88
|
+
export interface CodeAreaQuality {
|
|
89
|
+
defectDensity?: number;
|
|
90
|
+
churnRate?: number;
|
|
91
|
+
prRejectionRate?: number;
|
|
92
|
+
/** True when the code area produces frontend artifacts gated by the DSB. */
|
|
93
|
+
hasFrontendComponents: boolean;
|
|
94
|
+
/** Present only when `hasFrontendComponents === true`. */
|
|
95
|
+
designQuality?: DesignQualityMetrics;
|
|
96
|
+
}
|
|
97
|
+
export type DesignAuthoritySignalType = 'advances-design-coherence' | 'fills-catalog-gap' | 'fragments-component-catalog' | 'misaligned-with-brand' | 'unspecified';
|
|
98
|
+
export interface DesignAuthoritySignal {
|
|
99
|
+
/** True when the issue author/commenter is a DSB designAuthority principal. */
|
|
100
|
+
isDesignAuthority: boolean;
|
|
101
|
+
/** The signal type parsed from labels or structured comments. */
|
|
102
|
+
signalType?: DesignAuthoritySignalType;
|
|
103
|
+
/** The issue's code area compliance score in [0, 1] (used to modulate weight). */
|
|
104
|
+
areaComplianceScore?: number;
|
|
105
|
+
}
|
|
106
|
+
export interface AdmissionThresholds {
|
|
107
|
+
minimumScore: number;
|
|
108
|
+
minimumConfidence: number;
|
|
109
|
+
}
|
|
110
|
+
export interface IssueAdmissionResult {
|
|
111
|
+
admitted: boolean;
|
|
112
|
+
score: PriorityScore;
|
|
113
|
+
reason: string;
|
|
114
|
+
suggestions?: string[];
|
|
115
|
+
/**
|
|
116
|
+
* RFC-0008 §A.6 — pillar attribution + tension flags. Required on
|
|
117
|
+
* every admission result so reviewers can act on pillar mismatches.
|
|
118
|
+
*/
|
|
119
|
+
pillarBreakdown: PillarBreakdown;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Map GitHub issue fields to PPA PriorityInput dimensions.
|
|
123
|
+
*
|
|
124
|
+
* Heuristics (ported from dogfood/scripts/ppa-score.ts):
|
|
125
|
+
* - Labels → bug severity, soul alignment hints, builder conviction
|
|
126
|
+
* - Reactions → team consensus, customer request count
|
|
127
|
+
* - Comments → demand signal
|
|
128
|
+
* - Body complexity section → complexity score
|
|
129
|
+
* - Issue age → competitive drift
|
|
130
|
+
*/
|
|
131
|
+
export declare function mapIssueToPriorityInput(input: AdmissionInput): PriorityInput;
|
|
132
|
+
/**
|
|
133
|
+
* Score a GitHub issue for pipeline admission using the RFC-0008 §A.6
|
|
134
|
+
* admission-subset composite.
|
|
135
|
+
*
|
|
136
|
+
* P_admission = SA × D-pi_adjusted × ER × (1 + HC)
|
|
137
|
+
*
|
|
138
|
+
* M-phi, E-tau, C-kappa are deferred to runtime scoring — they apply
|
|
139
|
+
* when an admitted issue is picked up for execution, not at the gate.
|
|
140
|
+
*
|
|
141
|
+
* Returns whether the issue is admitted (score and confidence above
|
|
142
|
+
* thresholds) along with the full score and, if rejected, suggestions
|
|
143
|
+
* for improvement.
|
|
144
|
+
*/
|
|
145
|
+
export declare function scoreIssueForAdmission(input: AdmissionInput, thresholds: AdmissionThresholds, priorityConfig?: PriorityConfig, options?: import('./admission-composite.js').AdmissionCompositeOptions): IssueAdmissionResult;
|
|
146
|
+
/** Map backlog frontmatter priority string to the typed BacklogContext shape. */
|
|
147
|
+
export declare function normalizeBacklogPriority(p: string | null | undefined): BacklogContext['priority'];
|
|
148
|
+
//# sourceMappingURL=admission-score.d.ts.map
|