@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,173 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Model alias registry per RFC-0010 §11. Maps short aliases (haiku, sonnet, opus, opus[1m])
|
|
3
|
+
* to physical model IDs and tracks deprecation lifecycle (deprecatedAt / removedAt /
|
|
4
|
+
* replacementAlias). Resolution is performed once at pipeline-load and pinned per run
|
|
5
|
+
* (RFC §11.1) so model swaps cannot occur underneath an in-flight pipeline.
|
|
6
|
+
*/
|
|
7
|
+
export class ModelRemovedError extends Error {
|
|
8
|
+
alias;
|
|
9
|
+
modelId;
|
|
10
|
+
removedAt;
|
|
11
|
+
constructor(alias, modelId, removedAt) {
|
|
12
|
+
super(`Model alias '${alias}' resolves to '${modelId}', which was removed at ${removedAt}`);
|
|
13
|
+
this.alias = alias;
|
|
14
|
+
this.modelId = modelId;
|
|
15
|
+
this.removedAt = removedAt;
|
|
16
|
+
this.name = 'ModelRemovedError';
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
export class UnknownAliasError extends Error {
|
|
20
|
+
alias;
|
|
21
|
+
constructor(alias) {
|
|
22
|
+
super(`Unknown model alias: ${alias}`);
|
|
23
|
+
this.alias = alias;
|
|
24
|
+
this.name = 'UnknownAliasError';
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
const GRACE_PERIOD_DAYS = 30;
|
|
28
|
+
/**
|
|
29
|
+
* Default registry shipped with the orchestrator. Maintainers update deprecatedAt /
|
|
30
|
+
* removedAt / replacementAlias from public vendor announcements (see operator-runbook).
|
|
31
|
+
*/
|
|
32
|
+
export const DEFAULT_REGISTRY = [
|
|
33
|
+
{
|
|
34
|
+
alias: 'haiku',
|
|
35
|
+
modelId: 'claude-haiku-4-5-20251001',
|
|
36
|
+
deprecatedAt: null,
|
|
37
|
+
removedAt: null,
|
|
38
|
+
replacementAlias: null,
|
|
39
|
+
use: 'Classification, routing, formatting, structured-output extraction',
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
alias: 'sonnet',
|
|
43
|
+
modelId: 'claude-sonnet-4-6',
|
|
44
|
+
deprecatedAt: null,
|
|
45
|
+
removedAt: null,
|
|
46
|
+
replacementAlias: null,
|
|
47
|
+
use: 'Code review, refactoring, validation, default for everything else',
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
alias: 'opus',
|
|
51
|
+
modelId: 'claude-opus-4-7',
|
|
52
|
+
deprecatedAt: null,
|
|
53
|
+
removedAt: null,
|
|
54
|
+
replacementAlias: null,
|
|
55
|
+
use: 'Complex implementation, multi-file refactors, design work',
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
alias: 'opus[1m]',
|
|
59
|
+
modelId: 'claude-opus-4-7[1m]',
|
|
60
|
+
deprecatedAt: null,
|
|
61
|
+
removedAt: null,
|
|
62
|
+
replacementAlias: null,
|
|
63
|
+
use: 'Implementation against a large codebase context (>200K tokens)',
|
|
64
|
+
},
|
|
65
|
+
];
|
|
66
|
+
export class ModelRegistry {
|
|
67
|
+
entries;
|
|
68
|
+
constructor(entries = DEFAULT_REGISTRY) {
|
|
69
|
+
this.entries = new Map(entries.map((e) => [e.alias, { ...e }]));
|
|
70
|
+
}
|
|
71
|
+
list() {
|
|
72
|
+
return Array.from(this.entries.values()).map((e) => ({ ...e }));
|
|
73
|
+
}
|
|
74
|
+
get(alias) {
|
|
75
|
+
const e = this.entries.get(alias);
|
|
76
|
+
return e ? { ...e } : undefined;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Resolve an alias to a physical model ID at pipeline-load. Throws ModelRemovedError
|
|
80
|
+
* if the model has been removed; emits ModelDeprecated event otherwise (informational).
|
|
81
|
+
* Within `GRACE_PERIOD_DAYS` of the removal date, additionally emits
|
|
82
|
+
* ModelDeprecationGracePeriod for escalated operator notification.
|
|
83
|
+
*/
|
|
84
|
+
resolve(alias, ctx = {}) {
|
|
85
|
+
const entry = this.entries.get(alias);
|
|
86
|
+
if (!entry)
|
|
87
|
+
throw new UnknownAliasError(alias);
|
|
88
|
+
const now = (ctx.now ?? (() => new Date()))();
|
|
89
|
+
const events = [];
|
|
90
|
+
if (entry.removedAt) {
|
|
91
|
+
const removedAt = new Date(entry.removedAt);
|
|
92
|
+
if (now.getTime() >= removedAt.getTime()) {
|
|
93
|
+
throw new ModelRemovedError(alias, entry.modelId, entry.removedAt);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
if (entry.deprecatedAt) {
|
|
97
|
+
const deprecatedAt = new Date(entry.deprecatedAt);
|
|
98
|
+
if (now.getTime() >= deprecatedAt.getTime()) {
|
|
99
|
+
events.push({
|
|
100
|
+
type: 'ModelDeprecated',
|
|
101
|
+
alias,
|
|
102
|
+
modelId: entry.modelId,
|
|
103
|
+
removedAt: entry.removedAt,
|
|
104
|
+
replacementAlias: entry.replacementAlias,
|
|
105
|
+
});
|
|
106
|
+
if (entry.removedAt) {
|
|
107
|
+
const removedAt = new Date(entry.removedAt);
|
|
108
|
+
const graceCutoff = removedAt.getTime() - GRACE_PERIOD_DAYS * 24 * 60 * 60 * 1000;
|
|
109
|
+
if (now.getTime() >= graceCutoff) {
|
|
110
|
+
events.push({
|
|
111
|
+
type: 'ModelDeprecationGracePeriod',
|
|
112
|
+
alias,
|
|
113
|
+
removedAt: entry.removedAt,
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
if (events.length === 0) {
|
|
120
|
+
events.push({ type: 'ok', alias, modelId: entry.modelId });
|
|
121
|
+
}
|
|
122
|
+
return { modelId: entry.modelId, events };
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Bulk-resolve a set of stage aliases. Emits one ResolutionResult per (stage, alias).
|
|
126
|
+
* Used at pipeline-load to pin model resolution for the whole pipeline run.
|
|
127
|
+
*/
|
|
128
|
+
resolveAll(stageAliases, ctx = {}) {
|
|
129
|
+
const out = new Map();
|
|
130
|
+
for (const { stage, alias } of stageAliases) {
|
|
131
|
+
out.set(stage, this.resolve(alias, ctx));
|
|
132
|
+
}
|
|
133
|
+
return out;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Operator-facing dry-run helper: for each currently deprecated alias, report what
|
|
137
|
+
* would happen if a pipeline started today. Used by cli-model-bump --dry-run.
|
|
138
|
+
*/
|
|
139
|
+
bumpPlan(stageAliases, ctx = {}) {
|
|
140
|
+
const now = (ctx.now ?? (() => new Date()))();
|
|
141
|
+
const result = [];
|
|
142
|
+
for (const { stage, alias } of stageAliases) {
|
|
143
|
+
const entry = this.entries.get(alias);
|
|
144
|
+
if (!entry || !entry.deprecatedAt)
|
|
145
|
+
continue;
|
|
146
|
+
if (new Date(entry.deprecatedAt).getTime() > now.getTime())
|
|
147
|
+
continue;
|
|
148
|
+
let replacementModelId = null;
|
|
149
|
+
if (entry.replacementAlias) {
|
|
150
|
+
const replacement = this.entries.get(entry.replacementAlias);
|
|
151
|
+
replacementModelId = replacement?.modelId ?? null;
|
|
152
|
+
}
|
|
153
|
+
let inGracePeriod = false;
|
|
154
|
+
if (entry.removedAt) {
|
|
155
|
+
const removedAt = new Date(entry.removedAt);
|
|
156
|
+
const graceCutoff = removedAt.getTime() - GRACE_PERIOD_DAYS * 24 * 60 * 60 * 1000;
|
|
157
|
+
inGracePeriod = now.getTime() >= graceCutoff;
|
|
158
|
+
}
|
|
159
|
+
result.push({
|
|
160
|
+
stage,
|
|
161
|
+
alias,
|
|
162
|
+
currentModelId: entry.modelId,
|
|
163
|
+
deprecatedAt: entry.deprecatedAt,
|
|
164
|
+
removedAt: entry.removedAt,
|
|
165
|
+
replacementAlias: entry.replacementAlias,
|
|
166
|
+
replacementModelId,
|
|
167
|
+
inGracePeriod,
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
return result;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pillar breakdown & tension detection (RFC-0008 §A.6 + Amendment 6).
|
|
3
|
+
*
|
|
4
|
+
* The admission composite produces a single scalar, but downstream
|
|
5
|
+
* reviewers (product, design, engineering) want to see *which pillar*
|
|
6
|
+
* the score came from — so they can act on a mismatch between a
|
|
7
|
+
* strong product signal and a weak design or engineering one.
|
|
8
|
+
*
|
|
9
|
+
* This module takes the `AdmissionComposite.breakdown` emitted by
|
|
10
|
+
* `computeAdmissionComposite` and produces:
|
|
11
|
+
* - three `PillarContribution`s (product/design/engineering)
|
|
12
|
+
* - `SharedDimensions` (SA-3 placeholder + HC channel map)
|
|
13
|
+
* - tension flags detected from pillar mismatch
|
|
14
|
+
*/
|
|
15
|
+
import type { AdmissionComposite } from './admission-composite.js';
|
|
16
|
+
export type PillarName = 'product' | 'design' | 'engineering';
|
|
17
|
+
export type TensionFlagType = 'PRODUCT_HIGH_DESIGN_LOW' | 'PRODUCT_HIGH_ENGINEERING_LOW' | 'DESIGN_HIGH_PRODUCT_LOW' | 'ENGINEERING_HIGH_PRODUCT_LOW' | 'ALL_MEDIUM';
|
|
18
|
+
export interface PillarContribution {
|
|
19
|
+
pillar: PillarName;
|
|
20
|
+
/** PPA/RFC dimension labels attributed to this pillar at admission time. */
|
|
21
|
+
governedDimensions: string[];
|
|
22
|
+
/** Aggregate pillar signal in [0, 1]. */
|
|
23
|
+
signal: number;
|
|
24
|
+
/** Stable human-readable interpretation (snapshot-tested). */
|
|
25
|
+
interpretation: string;
|
|
26
|
+
}
|
|
27
|
+
export interface HcChannelBreakdown {
|
|
28
|
+
explicit: number;
|
|
29
|
+
consensus: number;
|
|
30
|
+
decision: number;
|
|
31
|
+
design: number;
|
|
32
|
+
}
|
|
33
|
+
export interface SharedDimensions {
|
|
34
|
+
/**
|
|
35
|
+
* SA-3 (shared intent) — unavailable at admission in Phase 1; M5
|
|
36
|
+
* populates this once the SA-1/SA-2/SA-3 decomposition lands.
|
|
37
|
+
*/
|
|
38
|
+
saAlpha3?: number;
|
|
39
|
+
/** Per-channel HC breakdown with the tanh composite for reference. */
|
|
40
|
+
hcComposite: HcChannelBreakdown & {
|
|
41
|
+
value: number;
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
export interface TensionFlag {
|
|
45
|
+
type: TensionFlagType;
|
|
46
|
+
/** Stable suggestion string per tension type (snapshot-tested). */
|
|
47
|
+
suggestedAction: string;
|
|
48
|
+
}
|
|
49
|
+
export interface PillarBreakdown {
|
|
50
|
+
product: PillarContribution;
|
|
51
|
+
design: PillarContribution;
|
|
52
|
+
engineering: PillarContribution;
|
|
53
|
+
shared: SharedDimensions;
|
|
54
|
+
tensions: TensionFlag[];
|
|
55
|
+
}
|
|
56
|
+
export declare function computePillarBreakdown(composite: AdmissionComposite): PillarBreakdown;
|
|
57
|
+
export declare function detectTensions(breakdown: PillarBreakdown): TensionFlag[];
|
|
58
|
+
/**
|
|
59
|
+
* Aggregate pillar signal in [0, 1]. Exposed so consumers can compute
|
|
60
|
+
* pillar scores without needing the full `AdmissionComposite`.
|
|
61
|
+
*/
|
|
62
|
+
export declare function pillarSignalScore(signals: readonly number[]): number;
|
|
63
|
+
//# sourceMappingURL=pillar-breakdown.d.ts.map
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pillar breakdown & tension detection (RFC-0008 §A.6 + Amendment 6).
|
|
3
|
+
*
|
|
4
|
+
* The admission composite produces a single scalar, but downstream
|
|
5
|
+
* reviewers (product, design, engineering) want to see *which pillar*
|
|
6
|
+
* the score came from — so they can act on a mismatch between a
|
|
7
|
+
* strong product signal and a weak design or engineering one.
|
|
8
|
+
*
|
|
9
|
+
* This module takes the `AdmissionComposite.breakdown` emitted by
|
|
10
|
+
* `computeAdmissionComposite` and produces:
|
|
11
|
+
* - three `PillarContribution`s (product/design/engineering)
|
|
12
|
+
* - `SharedDimensions` (SA-3 placeholder + HC channel map)
|
|
13
|
+
* - tension flags detected from pillar mismatch
|
|
14
|
+
*/
|
|
15
|
+
// ── Thresholds ─────────────────────────────────────────────────────────
|
|
16
|
+
const HIGH_THRESHOLD = 0.7;
|
|
17
|
+
const LOW_THRESHOLD = 0.3;
|
|
18
|
+
const MEDIUM_LOW = 0.3;
|
|
19
|
+
const MEDIUM_HIGH = 0.5;
|
|
20
|
+
// ── Suggested actions (stable) ─────────────────────────────────────────
|
|
21
|
+
const SUGGESTED_ACTIONS = Object.freeze({
|
|
22
|
+
PRODUCT_HIGH_DESIGN_LOW: 'Product intent is strong but design-system readiness is weak; consider catalog-first work or route through design authority before building.',
|
|
23
|
+
PRODUCT_HIGH_ENGINEERING_LOW: 'Product intent is strong but engineering signal is weak; address the defect-density, autonomy gap, or complexity before building.',
|
|
24
|
+
DESIGN_HIGH_PRODUCT_LOW: 'Design signal is strong but product demand is low; confirm product alignment before scheduling.',
|
|
25
|
+
ENGINEERING_HIGH_PRODUCT_LOW: 'Engineering area health is strong but product demand is weak; surface more demand evidence before scheduling.',
|
|
26
|
+
ALL_MEDIUM: 'All pillars are in the neutral band; the score is likely noise — gather more evidence or defer.',
|
|
27
|
+
});
|
|
28
|
+
// ── Public API ─────────────────────────────────────────────────────────
|
|
29
|
+
export function computePillarBreakdown(composite) {
|
|
30
|
+
const b = composite.breakdown;
|
|
31
|
+
// Product: SA-1 (soulAlignment proxy), D-pi, HC_explicit
|
|
32
|
+
const productSignal = mean([
|
|
33
|
+
b.soulAlignment,
|
|
34
|
+
b.demandPressureAdjusted,
|
|
35
|
+
normalizeSigned(b.humanCurve.hcExplicit),
|
|
36
|
+
]);
|
|
37
|
+
const product = {
|
|
38
|
+
pillar: 'product',
|
|
39
|
+
governedDimensions: ['SA-1', 'D-pi', 'HC_explicit'],
|
|
40
|
+
signal: productSignal,
|
|
41
|
+
interpretation: interpret('Product', productSignal, 'mission alignment, demand, and explicit priority'),
|
|
42
|
+
};
|
|
43
|
+
// Design: ER-4 (designSystemReadiness) + HC_design; SA-2 deferred to M5.
|
|
44
|
+
const designSignal = mean([b.designSystemReadiness, normalizeSigned(b.humanCurve.hcDesign)]);
|
|
45
|
+
const design = {
|
|
46
|
+
pillar: 'design',
|
|
47
|
+
governedDimensions: ['ER-4', 'HC_design'],
|
|
48
|
+
signal: designSignal,
|
|
49
|
+
interpretation: interpret('Design', designSignal, 'design-system readiness and design-authority signal'),
|
|
50
|
+
};
|
|
51
|
+
// Engineering: ER-1 (baseER), ER-2 (autonomyFactor), defectRiskFactor inverse.
|
|
52
|
+
// defectRiskFactor is clamped upstream to [0, 0.5]; the clamp01 here is
|
|
53
|
+
// a defence-in-depth guard so a regression in the upstream clamp can't
|
|
54
|
+
// feed a negative value into `mean()` and corrupt the engineering signal.
|
|
55
|
+
const engineeringSignal = mean([
|
|
56
|
+
b.baseExecutionReality,
|
|
57
|
+
b.autonomyFactor,
|
|
58
|
+
clamp01(1 - 2 * b.defectRiskFactor),
|
|
59
|
+
]);
|
|
60
|
+
const engineering = {
|
|
61
|
+
pillar: 'engineering',
|
|
62
|
+
governedDimensions: ['ER-1', 'ER-2', 'ER-3'],
|
|
63
|
+
signal: engineeringSignal,
|
|
64
|
+
interpretation: interpret('Engineering', engineeringSignal, 'complexity feasibility, autonomy gap, and code-area defect risk'),
|
|
65
|
+
};
|
|
66
|
+
const shared = {
|
|
67
|
+
hcComposite: {
|
|
68
|
+
explicit: b.humanCurve.hcExplicit,
|
|
69
|
+
consensus: b.humanCurve.hcConsensus,
|
|
70
|
+
decision: b.humanCurve.hcDecision,
|
|
71
|
+
design: b.humanCurve.hcDesign,
|
|
72
|
+
value: b.humanCurve.hcComposite,
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
const tensions = detectTensions({ product, design, engineering, shared, tensions: [] });
|
|
76
|
+
return { product, design, engineering, shared, tensions };
|
|
77
|
+
}
|
|
78
|
+
export function detectTensions(breakdown) {
|
|
79
|
+
const flags = [];
|
|
80
|
+
const p = breakdown.product.signal;
|
|
81
|
+
const d = breakdown.design.signal;
|
|
82
|
+
const e = breakdown.engineering.signal;
|
|
83
|
+
if (p > HIGH_THRESHOLD && d < LOW_THRESHOLD) {
|
|
84
|
+
flags.push({
|
|
85
|
+
type: 'PRODUCT_HIGH_DESIGN_LOW',
|
|
86
|
+
suggestedAction: SUGGESTED_ACTIONS.PRODUCT_HIGH_DESIGN_LOW,
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
if (p > HIGH_THRESHOLD && e < LOW_THRESHOLD) {
|
|
90
|
+
flags.push({
|
|
91
|
+
type: 'PRODUCT_HIGH_ENGINEERING_LOW',
|
|
92
|
+
suggestedAction: SUGGESTED_ACTIONS.PRODUCT_HIGH_ENGINEERING_LOW,
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
if (d > HIGH_THRESHOLD && p < LOW_THRESHOLD) {
|
|
96
|
+
flags.push({
|
|
97
|
+
type: 'DESIGN_HIGH_PRODUCT_LOW',
|
|
98
|
+
suggestedAction: SUGGESTED_ACTIONS.DESIGN_HIGH_PRODUCT_LOW,
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
if (e > HIGH_THRESHOLD && p < LOW_THRESHOLD) {
|
|
102
|
+
flags.push({
|
|
103
|
+
type: 'ENGINEERING_HIGH_PRODUCT_LOW',
|
|
104
|
+
suggestedAction: SUGGESTED_ACTIONS.ENGINEERING_HIGH_PRODUCT_LOW,
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
// ALL_MEDIUM: all three pillars strictly inside [MEDIUM_LOW, MEDIUM_HIGH]
|
|
108
|
+
if (inMediumBand(p) && inMediumBand(d) && inMediumBand(e)) {
|
|
109
|
+
flags.push({
|
|
110
|
+
type: 'ALL_MEDIUM',
|
|
111
|
+
suggestedAction: SUGGESTED_ACTIONS.ALL_MEDIUM,
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
return flags;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Aggregate pillar signal in [0, 1]. Exposed so consumers can compute
|
|
118
|
+
* pillar scores without needing the full `AdmissionComposite`.
|
|
119
|
+
*/
|
|
120
|
+
export function pillarSignalScore(signals) {
|
|
121
|
+
return mean(signals);
|
|
122
|
+
}
|
|
123
|
+
// ── Helpers ────────────────────────────────────────────────────────────
|
|
124
|
+
function mean(values) {
|
|
125
|
+
if (values.length === 0)
|
|
126
|
+
return 0;
|
|
127
|
+
const sum = values.reduce((acc, v) => acc + v, 0);
|
|
128
|
+
return clamp01(sum / values.length);
|
|
129
|
+
}
|
|
130
|
+
function clamp01(value) {
|
|
131
|
+
return Math.min(1, Math.max(0, value));
|
|
132
|
+
}
|
|
133
|
+
/** Map a signed [-1, 1] HC channel onto the pillar's unsigned [0, 1] scale. */
|
|
134
|
+
function normalizeSigned(value) {
|
|
135
|
+
return clamp01((value + 1) / 2);
|
|
136
|
+
}
|
|
137
|
+
function interpret(pillar, signal, what) {
|
|
138
|
+
const band = signalBand(signal);
|
|
139
|
+
return `${band} ${pillar} signal (${signal.toFixed(2)}) from ${what}`;
|
|
140
|
+
}
|
|
141
|
+
function signalBand(signal) {
|
|
142
|
+
if (signal >= HIGH_THRESHOLD)
|
|
143
|
+
return 'strong';
|
|
144
|
+
if (signal >= MEDIUM_HIGH)
|
|
145
|
+
return 'moderate';
|
|
146
|
+
if (signal >= MEDIUM_LOW)
|
|
147
|
+
return 'neutral';
|
|
148
|
+
return 'weak';
|
|
149
|
+
}
|
|
150
|
+
function inMediumBand(value) {
|
|
151
|
+
return value >= MEDIUM_LOW && value <= MEDIUM_HIGH;
|
|
152
|
+
}
|
|
153
|
+
//# sourceMappingURL=pillar-breakdown.js.map
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PipelineCycleDetector — tracks stage invocations per issue/PR across
|
|
3
|
+
* all workflow runs to detect infinite orchestration loops.
|
|
4
|
+
*
|
|
5
|
+
* Uses GitHub issue/PR comments as shared state (hidden HTML markers)
|
|
6
|
+
* to work across workflow boundaries.
|
|
7
|
+
*/
|
|
8
|
+
import type { IssueTracker } from '@ai-sdlc/reference';
|
|
9
|
+
export type PipelineStage = 'admission' | 'triage' | 'agent' | 'review' | 'fix-ci' | 'fix-review';
|
|
10
|
+
export interface CycleConfig {
|
|
11
|
+
/** Max invocations per stage (default: 3 for agent stages, 2 for fix stages). */
|
|
12
|
+
maxInvocations: Record<PipelineStage, number>;
|
|
13
|
+
}
|
|
14
|
+
export interface CycleDetectionResult {
|
|
15
|
+
cycleDetected: boolean;
|
|
16
|
+
loopingStages: Array<{
|
|
17
|
+
stage: PipelineStage;
|
|
18
|
+
count: number;
|
|
19
|
+
max: number;
|
|
20
|
+
}>;
|
|
21
|
+
totalInvocations: number;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Default max invocations per stage.
|
|
25
|
+
* These must be HIGHER than the per-stage retry limits (which are the
|
|
26
|
+
* primary guard). The cycle detector is a safety net for cross-stage
|
|
27
|
+
* loops, not a replacement for retry counting.
|
|
28
|
+
*
|
|
29
|
+
* Per-stage retry limits: fix-ci=2, fix-review=2
|
|
30
|
+
* Cycle limits: set to retry_limit + 2 to allow retries + headroom
|
|
31
|
+
*/
|
|
32
|
+
export declare const DEFAULT_CYCLE_LIMITS: Record<PipelineStage, number>;
|
|
33
|
+
/**
|
|
34
|
+
* Generate HTML comment marker for a stage invocation.
|
|
35
|
+
* Format: <!-- ai-sdlc-cycle:{stage}:{timestamp} -->
|
|
36
|
+
*/
|
|
37
|
+
export declare function createStageMarker(stage: PipelineStage): string;
|
|
38
|
+
/**
|
|
39
|
+
* Parse stage invocation markers from comment bodies.
|
|
40
|
+
* Returns a map of stage -> invocation count.
|
|
41
|
+
*/
|
|
42
|
+
export declare function parseStageInvocations(comments: string[]): Map<PipelineStage, number>;
|
|
43
|
+
export declare class PipelineCycleDetector {
|
|
44
|
+
private config;
|
|
45
|
+
constructor(config?: Partial<CycleConfig>);
|
|
46
|
+
/**
|
|
47
|
+
* Check if a cycle exists for the given issue/PR by analyzing comment history.
|
|
48
|
+
* @param pendingStage — if set, adds +1 to this stage's count to account for the upcoming invocation
|
|
49
|
+
*/
|
|
50
|
+
detectCycle(tracker: IssueTracker, issueOrPrId: string, pendingStage?: PipelineStage): Promise<CycleDetectionResult>;
|
|
51
|
+
/**
|
|
52
|
+
* Detect cycle from comment bodies (for testing without IssueTracker).
|
|
53
|
+
* @param pendingStage — if set, adds +1 to this stage's count for the pending invocation
|
|
54
|
+
*/
|
|
55
|
+
detectCycleFromComments(comments: string[], pendingStage?: PipelineStage): CycleDetectionResult;
|
|
56
|
+
/**
|
|
57
|
+
* Record a stage invocation by creating a marker.
|
|
58
|
+
* The caller should append this to their comment.
|
|
59
|
+
*/
|
|
60
|
+
recordInvocation(stage: PipelineStage): string;
|
|
61
|
+
/**
|
|
62
|
+
* Get the max invocation limit for a stage.
|
|
63
|
+
*/
|
|
64
|
+
getMaxInvocations(stage: PipelineStage): number;
|
|
65
|
+
/**
|
|
66
|
+
* Update max invocations for specific stages.
|
|
67
|
+
*/
|
|
68
|
+
updateMaxInvocations(overrides: Partial<Record<PipelineStage, number>>): void;
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=pipeline-cycle-detector.d.ts.map
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PipelineCycleDetector — tracks stage invocations per issue/PR across
|
|
3
|
+
* all workflow runs to detect infinite orchestration loops.
|
|
4
|
+
*
|
|
5
|
+
* Uses GitHub issue/PR comments as shared state (hidden HTML markers)
|
|
6
|
+
* to work across workflow boundaries.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Default max invocations per stage.
|
|
10
|
+
* These must be HIGHER than the per-stage retry limits (which are the
|
|
11
|
+
* primary guard). The cycle detector is a safety net for cross-stage
|
|
12
|
+
* loops, not a replacement for retry counting.
|
|
13
|
+
*
|
|
14
|
+
* Per-stage retry limits: fix-ci=2, fix-review=2
|
|
15
|
+
* Cycle limits: set to retry_limit + 2 to allow retries + headroom
|
|
16
|
+
*/
|
|
17
|
+
export const DEFAULT_CYCLE_LIMITS = {
|
|
18
|
+
admission: 5,
|
|
19
|
+
triage: 5,
|
|
20
|
+
agent: 5,
|
|
21
|
+
review: 4,
|
|
22
|
+
'fix-ci': 4,
|
|
23
|
+
'fix-review': 4,
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Generate HTML comment marker for a stage invocation.
|
|
27
|
+
* Format: <!-- ai-sdlc-cycle:{stage}:{timestamp} -->
|
|
28
|
+
*/
|
|
29
|
+
export function createStageMarker(stage) {
|
|
30
|
+
const timestamp = Date.now();
|
|
31
|
+
return `<!-- ai-sdlc-cycle:${stage}:${timestamp} -->`;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Parse stage invocation markers from comment bodies.
|
|
35
|
+
* Returns a map of stage -> invocation count.
|
|
36
|
+
*/
|
|
37
|
+
export function parseStageInvocations(comments) {
|
|
38
|
+
const counts = new Map();
|
|
39
|
+
// Non-backtracking pattern: stage names are alphanumeric with optional single hyphens
|
|
40
|
+
const markerPattern = /<!-- ai-sdlc-cycle:([a-z][a-z0-9-]{0,30}):(\d{1,15}) -->/g;
|
|
41
|
+
for (const body of comments) {
|
|
42
|
+
let match;
|
|
43
|
+
while ((match = markerPattern.exec(body)) !== null) {
|
|
44
|
+
const stage = match[1];
|
|
45
|
+
counts.set(stage, (counts.get(stage) ?? 0) + 1);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return counts;
|
|
49
|
+
}
|
|
50
|
+
export class PipelineCycleDetector {
|
|
51
|
+
config;
|
|
52
|
+
constructor(config) {
|
|
53
|
+
this.config = {
|
|
54
|
+
maxInvocations: { ...DEFAULT_CYCLE_LIMITS, ...config?.maxInvocations },
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Check if a cycle exists for the given issue/PR by analyzing comment history.
|
|
59
|
+
* @param pendingStage — if set, adds +1 to this stage's count to account for the upcoming invocation
|
|
60
|
+
*/
|
|
61
|
+
async detectCycle(tracker, issueOrPrId, pendingStage) {
|
|
62
|
+
const comments = await tracker.getComments(issueOrPrId);
|
|
63
|
+
const commentBodies = comments.map((c) => c.body);
|
|
64
|
+
return this.detectCycleFromComments(commentBodies, pendingStage);
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Detect cycle from comment bodies (for testing without IssueTracker).
|
|
68
|
+
* @param pendingStage — if set, adds +1 to this stage's count for the pending invocation
|
|
69
|
+
*/
|
|
70
|
+
detectCycleFromComments(comments, pendingStage) {
|
|
71
|
+
const invocations = parseStageInvocations(comments);
|
|
72
|
+
// Account for the pending invocation that hasn't been recorded yet
|
|
73
|
+
if (pendingStage) {
|
|
74
|
+
invocations.set(pendingStage, (invocations.get(pendingStage) ?? 0) + 1);
|
|
75
|
+
}
|
|
76
|
+
const loopingStages = [];
|
|
77
|
+
let totalInvocations = 0;
|
|
78
|
+
for (const [stage, count] of invocations.entries()) {
|
|
79
|
+
totalInvocations += count;
|
|
80
|
+
const max = this.config.maxInvocations[stage];
|
|
81
|
+
if (count >= max) {
|
|
82
|
+
loopingStages.push({ stage, count, max });
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return {
|
|
86
|
+
cycleDetected: loopingStages.length > 0,
|
|
87
|
+
loopingStages,
|
|
88
|
+
totalInvocations,
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Record a stage invocation by creating a marker.
|
|
93
|
+
* The caller should append this to their comment.
|
|
94
|
+
*/
|
|
95
|
+
recordInvocation(stage) {
|
|
96
|
+
return createStageMarker(stage);
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Get the max invocation limit for a stage.
|
|
100
|
+
*/
|
|
101
|
+
getMaxInvocations(stage) {
|
|
102
|
+
return this.config.maxInvocations[stage];
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Update max invocations for specific stages.
|
|
106
|
+
*/
|
|
107
|
+
updateMaxInvocations(overrides) {
|
|
108
|
+
this.config.maxInvocations = { ...this.config.maxInvocations, ...overrides };
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=pipeline-cycle-detector.js.map
|
package/dist/priority.d.ts
CHANGED
|
@@ -10,82 +10,13 @@
|
|
|
10
10
|
*
|
|
11
11
|
* RFC reference: PPA section (priority scoring).
|
|
12
12
|
*/
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
entropyTax: number;
|
|
21
|
-
humanCurve: number;
|
|
22
|
-
calibration: number;
|
|
23
|
-
};
|
|
24
|
-
confidence: number;
|
|
25
|
-
timestamp: string;
|
|
26
|
-
/** Present when the score was produced via override. */
|
|
27
|
-
override?: {
|
|
28
|
-
reason: string;
|
|
29
|
-
expiry?: string;
|
|
30
|
-
};
|
|
31
|
-
}
|
|
32
|
-
export interface PriorityInput {
|
|
33
|
-
/** Work item identifier */
|
|
34
|
-
itemId: string;
|
|
35
|
-
/** Work item title and description for semantic analysis */
|
|
36
|
-
title: string;
|
|
37
|
-
description: string;
|
|
38
|
-
/** Labels/tags on the work item */
|
|
39
|
-
labels?: string[];
|
|
40
|
-
/** Pre-computed soul alignment score, or undefined to skip */
|
|
41
|
-
soulAlignment?: number;
|
|
42
|
-
/** Number of customer requests for this feature */
|
|
43
|
-
customerRequestCount?: number;
|
|
44
|
-
/** Recency-weighted demand signal [0, 1] */
|
|
45
|
-
demandSignal?: number;
|
|
46
|
-
/** Bug severity if this is a bug (1-5, 5=critical) */
|
|
47
|
-
bugSeverity?: number;
|
|
48
|
-
/** Builder conviction / roadmap priority [0, 1] */
|
|
49
|
-
builderConviction?: number;
|
|
50
|
-
/** Technology inflection relevance [0, 1] */
|
|
51
|
-
techInflection?: number;
|
|
52
|
-
/** Competitive pressure relevance [0, 1] */
|
|
53
|
-
competitivePressure?: number;
|
|
54
|
-
/** Regulatory urgency [0, 1] */
|
|
55
|
-
regulatoryUrgency?: number;
|
|
56
|
-
/** Task complexity from parseComplexity() (1-10) */
|
|
57
|
-
complexity?: number;
|
|
58
|
-
/** Budget utilization percent from CostTracker */
|
|
59
|
-
budgetUtilization?: number;
|
|
60
|
-
/** Are dependencies clear? [0, 1] */
|
|
61
|
-
dependencyClearance?: number;
|
|
62
|
-
/** Competitive drift score [0, 1] */
|
|
63
|
-
competitiveDrift?: number;
|
|
64
|
-
/** Market divergence [0, 1] */
|
|
65
|
-
marketDivergence?: number;
|
|
66
|
-
/** Explicit priority from backlog tool [0, 1] */
|
|
67
|
-
explicitPriority?: number;
|
|
68
|
-
/** Team consensus signal (votes, watchers) [0, 1] */
|
|
69
|
-
teamConsensus?: number;
|
|
70
|
-
/** Meeting decision weight [0, 1] */
|
|
71
|
-
meetingDecision?: number;
|
|
72
|
-
/** Override flag — if true, bypasses algorithm */
|
|
73
|
-
override?: boolean;
|
|
74
|
-
/** Override reason (required when override=true) */
|
|
75
|
-
overrideReason?: string;
|
|
76
|
-
/** Override expiry ISO timestamp */
|
|
77
|
-
overrideExpiry?: string;
|
|
78
|
-
}
|
|
79
|
-
export interface PriorityConfig {
|
|
80
|
-
/** Weights for human curve sub-components */
|
|
81
|
-
humanCurveWeights?: {
|
|
82
|
-
explicit?: number;
|
|
83
|
-
consensus?: number;
|
|
84
|
-
decision?: number;
|
|
85
|
-
};
|
|
86
|
-
/** Calibration coefficient (default 1.0) */
|
|
87
|
-
calibrationCoefficient?: number;
|
|
88
|
-
}
|
|
13
|
+
import type { PriorityScore, PriorityInput, PriorityConfig } from '@ai-sdlc/reference';
|
|
14
|
+
export type { PriorityScore, PriorityInput, PriorityConfig };
|
|
15
|
+
/**
|
|
16
|
+
* Compute a confidence score [0, 1] based on the fraction of optional
|
|
17
|
+
* input fields that were explicitly provided (not defaulted).
|
|
18
|
+
*/
|
|
19
|
+
export declare function computeConfidence(input: PriorityInput): number;
|
|
89
20
|
/**
|
|
90
21
|
* Compute the PPA composite priority score for a single work item.
|
|
91
22
|
*
|