@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,237 @@
|
|
|
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 { computeAdmissionComposite } from './admission-composite.js';
|
|
9
|
+
import { computePillarBreakdown } from './pillar-breakdown.js';
|
|
10
|
+
// ── Mapping ──────────────────────────────────────────────────────────
|
|
11
|
+
/**
|
|
12
|
+
* Map GitHub issue fields to PPA PriorityInput dimensions.
|
|
13
|
+
*
|
|
14
|
+
* Heuristics (ported from dogfood/scripts/ppa-score.ts):
|
|
15
|
+
* - Labels → bug severity, soul alignment hints, builder conviction
|
|
16
|
+
* - Reactions → team consensus, customer request count
|
|
17
|
+
* - Comments → demand signal
|
|
18
|
+
* - Body complexity section → complexity score
|
|
19
|
+
* - Issue age → competitive drift
|
|
20
|
+
*/
|
|
21
|
+
export function mapIssueToPriorityInput(input) {
|
|
22
|
+
const labels = input.labels;
|
|
23
|
+
const assoc = input.authorAssociation ?? 'NONE';
|
|
24
|
+
const backlog = input.backlogContext;
|
|
25
|
+
// ── Backlog status veto ─────────────────────────────────────
|
|
26
|
+
// Drafts aren't ready to admit; orchestrator should ignore them.
|
|
27
|
+
if (backlog?.status === 'Draft') {
|
|
28
|
+
return {
|
|
29
|
+
itemId: `#${input.issueNumber}`,
|
|
30
|
+
title: input.title,
|
|
31
|
+
description: input.body ?? '',
|
|
32
|
+
labels,
|
|
33
|
+
soulAlignment: 0,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
// ── Trust-based signal boosting ────────────────────────────────
|
|
37
|
+
// Trusted sources (project team) get baseline conviction and demand.
|
|
38
|
+
// Untrusted sources need external validation (reactions, comments).
|
|
39
|
+
const isTrusted = assoc === 'OWNER' || assoc === 'MEMBER' || assoc === 'COLLABORATOR';
|
|
40
|
+
const isContributor = assoc === 'CONTRIBUTOR';
|
|
41
|
+
// ── Complexity from issue body, AC count, or backlog context ─
|
|
42
|
+
const complexityMatch = input.body?.match(/###?\s*Complexity\s*\n+\s*(\d+)/i);
|
|
43
|
+
let complexity = complexityMatch ? Number(complexityMatch[1]) : undefined;
|
|
44
|
+
// Backlog tasks rarely include a `### Complexity` header — fall back to AC count
|
|
45
|
+
// (each AC is roughly one logical unit; clamp at 10).
|
|
46
|
+
if (complexity === undefined && backlog?.acceptanceCriteriaCount !== undefined) {
|
|
47
|
+
complexity = Math.min(10, Math.max(1, Math.ceil(backlog.acceptanceCriteriaCount * 1.2)));
|
|
48
|
+
}
|
|
49
|
+
// ── Bug severity from labels ─────────────────────────────────
|
|
50
|
+
let bugSeverity;
|
|
51
|
+
if (labels.includes('critical') || labels.includes('P0'))
|
|
52
|
+
bugSeverity = 5;
|
|
53
|
+
else if (labels.includes('bug'))
|
|
54
|
+
bugSeverity = 3;
|
|
55
|
+
// ── Soul alignment heuristic from labels ─────────────────────
|
|
56
|
+
let soulAlignment = 0.5;
|
|
57
|
+
if (labels.includes('security') || labels.includes('security-triage'))
|
|
58
|
+
soulAlignment = 0.7;
|
|
59
|
+
if (labels.includes('enhancement'))
|
|
60
|
+
soulAlignment = 0.6;
|
|
61
|
+
if (labels.includes('governance') || labels.includes('compliance'))
|
|
62
|
+
soulAlignment = 0.85;
|
|
63
|
+
if (labels.includes('spec') || labels.includes('rfc'))
|
|
64
|
+
soulAlignment = 0.9;
|
|
65
|
+
// Backlog-specific labels — RFC process work directly serves project mission;
|
|
66
|
+
// tech-debt is operationally important but not mission-defining.
|
|
67
|
+
if (labels.includes('rfc-process') || labels.includes('architecture'))
|
|
68
|
+
soulAlignment = 0.85;
|
|
69
|
+
if (labels.includes('tech-debt') && soulAlignment < 0.55)
|
|
70
|
+
soulAlignment = 0.55;
|
|
71
|
+
// Trusted authors get a soul alignment floor — they know the project mission
|
|
72
|
+
if (isTrusted && soulAlignment < 0.6)
|
|
73
|
+
soulAlignment = 0.6;
|
|
74
|
+
// ── Reactions → demand / consensus ───────────────────────────
|
|
75
|
+
const reactionConsensus = Math.min(1, input.reactionCount / 5);
|
|
76
|
+
// Trusted sources carry implicit team consensus
|
|
77
|
+
const teamConsensus = isTrusted ? Math.max(0.5, reactionConsensus) : reactionConsensus;
|
|
78
|
+
// ── Comment count → demand signal ────────────────────────────
|
|
79
|
+
const commentDemand = Math.min(1, input.commentCount / 5);
|
|
80
|
+
// Trusted sources filing an issue IS demand — they wouldn't file it otherwise
|
|
81
|
+
const demandSignal = isTrusted
|
|
82
|
+
? Math.max(0.4, commentDemand)
|
|
83
|
+
: isContributor
|
|
84
|
+
? Math.max(0.2, commentDemand)
|
|
85
|
+
: commentDemand;
|
|
86
|
+
// ── Builder conviction ─────────────────────────────────────────
|
|
87
|
+
// Trusted: high conviction (they're the builders)
|
|
88
|
+
// Contributor: moderate (proven track record)
|
|
89
|
+
// ai-eligible label: explicit signal
|
|
90
|
+
// Default: low (needs validation)
|
|
91
|
+
let builderConviction = labels.includes('ai-eligible')
|
|
92
|
+
? 0.8
|
|
93
|
+
: isTrusted
|
|
94
|
+
? 0.8
|
|
95
|
+
: isContributor
|
|
96
|
+
? 0.6
|
|
97
|
+
: 0.4;
|
|
98
|
+
// Backlog tasks blocked by other work get a conviction penalty — the team
|
|
99
|
+
// can't confidently dispatch them until upstream lands.
|
|
100
|
+
if (backlog?.dependencyCount && backlog.dependencyCount > 0) {
|
|
101
|
+
builderConviction = Math.max(0.2, builderConviction - 0.3);
|
|
102
|
+
}
|
|
103
|
+
// ── Age → competitive drift ──────────────────────────────────
|
|
104
|
+
const ageMs = Date.now() - new Date(input.createdAt).getTime();
|
|
105
|
+
const ageDays = ageMs / (1000 * 60 * 60 * 24);
|
|
106
|
+
const competitiveDrift = Math.min(1, Math.max(0, (ageDays - 30) / 180));
|
|
107
|
+
// ── Security-rejected veto ───────────────────────────────────
|
|
108
|
+
if (labels.includes('security-rejected')) {
|
|
109
|
+
return {
|
|
110
|
+
itemId: `#${input.issueNumber}`,
|
|
111
|
+
title: input.title,
|
|
112
|
+
description: input.body ?? '',
|
|
113
|
+
labels,
|
|
114
|
+
soulAlignment: 0, // veto
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
// ── Explicit priority — labels first, then backlog frontmatter ──
|
|
118
|
+
let explicitPriority;
|
|
119
|
+
if (labels.includes('high'))
|
|
120
|
+
explicitPriority = 0.8;
|
|
121
|
+
else if (labels.includes('low'))
|
|
122
|
+
explicitPriority = 0.2;
|
|
123
|
+
else if (backlog?.priority) {
|
|
124
|
+
explicitPriority = mapBacklogPriorityToScalar(backlog.priority);
|
|
125
|
+
}
|
|
126
|
+
return {
|
|
127
|
+
itemId: `#${input.issueNumber}`,
|
|
128
|
+
title: input.title,
|
|
129
|
+
description: input.body ?? '',
|
|
130
|
+
labels,
|
|
131
|
+
soulAlignment,
|
|
132
|
+
bugSeverity,
|
|
133
|
+
customerRequestCount: input.reactionCount,
|
|
134
|
+
demandSignal,
|
|
135
|
+
builderConviction,
|
|
136
|
+
complexity,
|
|
137
|
+
competitiveDrift,
|
|
138
|
+
teamConsensus,
|
|
139
|
+
explicitPriority,
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
/** Map backlog frontmatter priority string to a scalar in [0,1]. */
|
|
143
|
+
function mapBacklogPriorityToScalar(p) {
|
|
144
|
+
switch (p) {
|
|
145
|
+
case 'critical':
|
|
146
|
+
return 1.0;
|
|
147
|
+
case 'high':
|
|
148
|
+
return 0.8;
|
|
149
|
+
case 'medium':
|
|
150
|
+
return 0.5;
|
|
151
|
+
case 'low':
|
|
152
|
+
return 0.2;
|
|
153
|
+
default:
|
|
154
|
+
return 0.5;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
// ── Suggestions ──────────────────────────────────────────────────────
|
|
158
|
+
function generateSuggestions(input, score) {
|
|
159
|
+
const suggestions = [];
|
|
160
|
+
const d = score.dimensions;
|
|
161
|
+
if (score.confidence < 0.2) {
|
|
162
|
+
suggestions.push('Add more detail to improve scoring confidence (complexity, acceptance criteria, labels)');
|
|
163
|
+
}
|
|
164
|
+
if (!input.body?.match(/###?\s*Complexity\s*\n/i)) {
|
|
165
|
+
suggestions.push('Add a `### Complexity` section with a score from 1-10');
|
|
166
|
+
}
|
|
167
|
+
if (!input.body?.match(/###?\s*Acceptance Criteria/i)) {
|
|
168
|
+
suggestions.push('Add an `### Acceptance Criteria` section with testable criteria');
|
|
169
|
+
}
|
|
170
|
+
if (input.body.length < 50) {
|
|
171
|
+
suggestions.push('Provide a more detailed description of the problem or feature');
|
|
172
|
+
}
|
|
173
|
+
const assoc = input.authorAssociation ?? 'NONE';
|
|
174
|
+
const isTrusted = assoc === 'OWNER' || assoc === 'MEMBER' || assoc === 'COLLABORATOR';
|
|
175
|
+
if (d.demandPressure < 0.3 && !isTrusted) {
|
|
176
|
+
suggestions.push('Low demand signal — add reactions or comments to show interest');
|
|
177
|
+
}
|
|
178
|
+
if (d.soulAlignment < 0.5) {
|
|
179
|
+
suggestions.push('Add labels that indicate alignment with the project mission (e.g., governance, spec, security)');
|
|
180
|
+
}
|
|
181
|
+
return suggestions;
|
|
182
|
+
}
|
|
183
|
+
// ── Public API ───────────────────────────────────────────────────────
|
|
184
|
+
/**
|
|
185
|
+
* Score a GitHub issue for pipeline admission using the RFC-0008 §A.6
|
|
186
|
+
* admission-subset composite.
|
|
187
|
+
*
|
|
188
|
+
* P_admission = SA × D-pi_adjusted × ER × (1 + HC)
|
|
189
|
+
*
|
|
190
|
+
* M-phi, E-tau, C-kappa are deferred to runtime scoring — they apply
|
|
191
|
+
* when an admitted issue is picked up for execution, not at the gate.
|
|
192
|
+
*
|
|
193
|
+
* Returns whether the issue is admitted (score and confidence above
|
|
194
|
+
* thresholds) along with the full score and, if rejected, suggestions
|
|
195
|
+
* for improvement.
|
|
196
|
+
*/
|
|
197
|
+
export function scoreIssueForAdmission(input, thresholds, priorityConfig, options) {
|
|
198
|
+
const composite = computeAdmissionComposite(input, priorityConfig, options);
|
|
199
|
+
const { score } = composite;
|
|
200
|
+
const pillarBreakdown = computePillarBreakdown(composite);
|
|
201
|
+
const scorePasses = score.composite >= thresholds.minimumScore;
|
|
202
|
+
const confidencePasses = score.confidence >= thresholds.minimumConfidence;
|
|
203
|
+
const admitted = scorePasses && confidencePasses;
|
|
204
|
+
if (admitted) {
|
|
205
|
+
return {
|
|
206
|
+
admitted: true,
|
|
207
|
+
score,
|
|
208
|
+
reason: `Score ${score.composite.toFixed(4)} meets threshold ${thresholds.minimumScore} with ${(score.confidence * 100).toFixed(0)}% confidence`,
|
|
209
|
+
pillarBreakdown,
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
const reasons = [];
|
|
213
|
+
if (!scorePasses) {
|
|
214
|
+
reasons.push(`score ${score.composite.toFixed(4)} below minimum ${thresholds.minimumScore}`);
|
|
215
|
+
}
|
|
216
|
+
if (!confidencePasses) {
|
|
217
|
+
reasons.push(`confidence ${(score.confidence * 100).toFixed(0)}% below minimum ${(thresholds.minimumConfidence * 100).toFixed(0)}%`);
|
|
218
|
+
}
|
|
219
|
+
return {
|
|
220
|
+
admitted: false,
|
|
221
|
+
score,
|
|
222
|
+
reason: `Not admitted: ${reasons.join('; ')}`,
|
|
223
|
+
suggestions: generateSuggestions(input, score),
|
|
224
|
+
pillarBreakdown,
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
/** Map backlog frontmatter priority string to the typed BacklogContext shape. */
|
|
228
|
+
export function normalizeBacklogPriority(p) {
|
|
229
|
+
if (!p)
|
|
230
|
+
return undefined;
|
|
231
|
+
const lower = p.toLowerCase().trim();
|
|
232
|
+
if (lower === 'critical' || lower === 'high' || lower === 'medium' || lower === 'low') {
|
|
233
|
+
return lower;
|
|
234
|
+
}
|
|
235
|
+
return undefined;
|
|
236
|
+
}
|
|
237
|
+
//# sourceMappingURL=admission-score.js.map
|
|
@@ -30,8 +30,9 @@ export async function analyzeCodebase(options) {
|
|
|
30
30
|
const moduleGraph = await buildModuleGraph(files, modules, options.repoPath);
|
|
31
31
|
// Step 5: Detect architectural patterns
|
|
32
32
|
const architecturalPatterns = detectPatterns(files, modules);
|
|
33
|
-
// Step 6: Detect conventions
|
|
34
|
-
|
|
33
|
+
// Step 6: Detect conventions (project-config-aware: package.json, vite.config.*,
|
|
34
|
+
// tsconfig.json, jsconfig.json, webpack.config.* — see AISDLC-80).
|
|
35
|
+
const conventions = await detectConventions(files, { repoPath: options.repoPath });
|
|
35
36
|
// Step 7: Analyze hotspots
|
|
36
37
|
const hotspots = await analyzeHotspots(options.repoPath, files, importsByFile, {
|
|
37
38
|
historyDays,
|
|
@@ -1,9 +1,92 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Detect coding conventions: naming style, test organization, import style.
|
|
3
|
+
*
|
|
4
|
+
* The detector accepts an optional `repoPath` so it can read project-level
|
|
5
|
+
* configuration (`package.json`, `vite.config.{js,ts}`, `tsconfig.json`,
|
|
6
|
+
* `jsconfig.json`, `webpack.config.*`) to interpret the file list more
|
|
7
|
+
* accurately. When `repoPath` is omitted the detector falls back to a pure
|
|
8
|
+
* file-name analysis (the original v1 behaviour).
|
|
9
|
+
*
|
|
10
|
+
* Three classes of false-positives motivated the project-config plumbing
|
|
11
|
+
* (AISDLC-80):
|
|
12
|
+
*
|
|
13
|
+
* 1. React projects mix PascalCase (components) with camelCase (hooks/stores
|
|
14
|
+
* and plain modules) — the v1 detector flagged this as `mixed`. With
|
|
15
|
+
* `package.json` `dependencies.react` visible we treat the dual-pattern
|
|
16
|
+
* case as the expected React convention.
|
|
17
|
+
* 2. Many repos host tests in multiple directories (`tests/`, `tests/e2e/`,
|
|
18
|
+
* `src/tests/`, `cypress/`, ...) plus collocated `*.test.*`. The v1
|
|
19
|
+
* detector picked one bucket and called it `mixed` when the proportions
|
|
20
|
+
* were close. We now enumerate the FULL set of locations.
|
|
21
|
+
* 3. Vite / TS / webpack path aliases (`@components`, `@engine`, ...) were
|
|
22
|
+
* classified as external imports because the v1 detector never read the
|
|
23
|
+
* alias maps. We now parse the alias map from each known config file and
|
|
24
|
+
* report alias usage as its own bucket.
|
|
3
25
|
*/
|
|
4
26
|
import type { FileInfo, DetectedConvention } from './types.js';
|
|
5
27
|
/**
|
|
6
|
-
*
|
|
28
|
+
* Each entry describes ONE place tests live in the repo. We enumerate ALL of
|
|
29
|
+
* them rather than flatten to a single label — a repo with `tests/`,
|
|
30
|
+
* `tests/e2e/`, `src/tests/` and a few collocated `*.test.*` files is reported
|
|
31
|
+
* with all four buckets visible (AISDLC-80).
|
|
7
32
|
*/
|
|
8
|
-
export
|
|
33
|
+
export interface TestLocationSummary {
|
|
34
|
+
/** Stable label for the bucket (e.g. `__tests__/`, `tests/e2e/`, `co-located`). */
|
|
35
|
+
label: string;
|
|
36
|
+
/** Number of test files matched against this bucket. */
|
|
37
|
+
count: number;
|
|
38
|
+
/** Up to three example file paths from this bucket. */
|
|
39
|
+
examples: string[];
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Classify every test file found into ALL the locations it actually lives,
|
|
43
|
+
* preserving the multi-directory reality of real projects. Returns the
|
|
44
|
+
* complete set sorted by file count (descending) with examples for each.
|
|
45
|
+
*/
|
|
46
|
+
export declare function enumerateTestLocations(files: FileInfo[]): TestLocationSummary[];
|
|
47
|
+
/** Map of alias prefix (e.g. `@components`) → resolved target glob. */
|
|
48
|
+
export type PathAliasMap = Record<string, string>;
|
|
49
|
+
/**
|
|
50
|
+
* Parse `compilerOptions.paths` from a `tsconfig.json` / `jsconfig.json`.
|
|
51
|
+
* The TS config format maps `"@components/*": ["src/components/*"]` — we
|
|
52
|
+
* normalise to `@components` → `src/components/*`.
|
|
53
|
+
*/
|
|
54
|
+
export declare function parseTsConfigAliases(content: string): PathAliasMap;
|
|
55
|
+
/**
|
|
56
|
+
* Extract `resolve.alias` (object literal form) from a Vite or webpack config
|
|
57
|
+
* file. We use a regex rather than a full JS parser because the contents are
|
|
58
|
+
* config files written in a small, well-known shape — the v1 detector's
|
|
59
|
+
* "regex over AST" tradeoff carries forward.
|
|
60
|
+
*
|
|
61
|
+
* Recognises both:
|
|
62
|
+
* resolve: { alias: { '@components': path.resolve(__dirname, 'src/components') } }
|
|
63
|
+
* alias: { '@engine': '/abs/path' }
|
|
64
|
+
*/
|
|
65
|
+
export declare function parseViteOrWebpackAliases(content: string): PathAliasMap;
|
|
66
|
+
/**
|
|
67
|
+
* Read every alias source we know about and merge into a single map. Sources
|
|
68
|
+
* are read in parallel; later sources take precedence if there is overlap.
|
|
69
|
+
*/
|
|
70
|
+
export declare function loadProjectAliases(repoPath: string): Promise<PathAliasMap>;
|
|
71
|
+
/**
|
|
72
|
+
* Read `package.json` and decide whether this is a React project. Looks at
|
|
73
|
+
* `dependencies` AND `devDependencies` because Vite-driven SPAs sometimes
|
|
74
|
+
* declare React as a dev dep via templates.
|
|
75
|
+
*/
|
|
76
|
+
export declare function detectReactProject(repoPath: string): Promise<boolean>;
|
|
77
|
+
export interface DetectConventionsOptions {
|
|
78
|
+
/**
|
|
79
|
+
* Absolute path to the repo root. When provided the detector reads project
|
|
80
|
+
* configs (`package.json`, vite/tsconfig/jsconfig/webpack) for context-aware
|
|
81
|
+
* decisions. Without it the detector falls back to pure file-name analysis.
|
|
82
|
+
*/
|
|
83
|
+
repoPath?: string;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Detect coding conventions from the file list. When `options.repoPath` is
|
|
87
|
+
* supplied the detector additionally reads project-level configuration to
|
|
88
|
+
* suppress the three classes of false-positives described at the top of this
|
|
89
|
+
* file (AISDLC-80).
|
|
90
|
+
*/
|
|
91
|
+
export declare function detectConventions(files: FileInfo[], options?: DetectConventionsOptions): Promise<DetectedConvention[]>;
|
|
9
92
|
//# sourceMappingURL=convention-detector.d.ts.map
|