@jterrats/open-orchestra 1.0.7 → 1.0.9
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/AGENTS.md +12 -2
- package/CHANGELOG.md +41 -0
- package/CLAUDE.md +13 -2
- package/dist/acceptance-criteria-quality.d.ts +12 -0
- package/dist/acceptance-criteria-quality.js +137 -0
- package/dist/acceptance-criteria-quality.js.map +1 -0
- package/dist/architecture-debt-inventory.d.ts +31 -0
- package/dist/architecture-debt-inventory.js +200 -0
- package/dist/architecture-debt-inventory.js.map +1 -0
- package/dist/architecture-debt-report.d.ts +2 -0
- package/dist/architecture-debt-report.js +28 -0
- package/dist/architecture-debt-report.js.map +1 -0
- package/dist/autonomous-phase-lifecycle.d.ts +5 -1
- package/dist/autonomous-phase-lifecycle.js +87 -17
- package/dist/autonomous-phase-lifecycle.js.map +1 -1
- package/dist/cli-payloads.d.ts +4 -0
- package/dist/cli-payloads.js +24 -0
- package/dist/cli-payloads.js.map +1 -0
- package/dist/cli.js +4 -446
- package/dist/cli.js.map +1 -1
- package/dist/command-manifest.js +3 -1
- package/dist/command-manifest.js.map +1 -1
- package/dist/command-route-utils.d.ts +18 -0
- package/dist/command-route-utils.js +18 -0
- package/dist/command-route-utils.js.map +1 -0
- package/dist/command-routes-integrations.d.ts +2 -0
- package/dist/command-routes-integrations.js +82 -0
- package/dist/command-routes-integrations.js.map +1 -0
- package/dist/command-routes.d.ts +2 -0
- package/dist/command-routes.js +175 -0
- package/dist/command-routes.js.map +1 -0
- package/dist/commands.d.ts +1 -1
- package/dist/commands.js +16 -3
- package/dist/commands.js.map +1 -1
- package/dist/github.js +22 -7
- package/dist/github.js.map +1 -1
- package/dist/metrics-commands.js +69 -17
- package/dist/metrics-commands.js.map +1 -1
- package/dist/phase-executor.js +5 -169
- package/dist/phase-executor.js.map +1 -1
- package/dist/phase-playbooks.js +17 -0
- package/dist/phase-playbooks.js.map +1 -1
- package/dist/qa-e2e-artifacts.d.ts +7 -0
- package/dist/qa-e2e-artifacts.js +225 -0
- package/dist/qa-e2e-artifacts.js.map +1 -0
- package/dist/quality-contracts.d.ts +83 -0
- package/dist/quality-contracts.js +463 -0
- package/dist/quality-contracts.js.map +1 -0
- package/dist/refresh-generated.js +87 -45
- package/dist/refresh-generated.js.map +1 -1
- package/dist/runtime-bootstrap-targets.d.ts +15 -0
- package/dist/runtime-bootstrap-targets.js +68 -0
- package/dist/runtime-bootstrap-targets.js.map +1 -0
- package/dist/runtime-bootstrap.js +3 -0
- package/dist/runtime-bootstrap.js.map +1 -1
- package/dist/runtime-commands.d.ts +2 -0
- package/dist/runtime-commands.js +187 -2
- package/dist/runtime-commands.js.map +1 -1
- package/dist/runtime-context-manifest.d.ts +27 -0
- package/dist/runtime-context-manifest.js +151 -0
- package/dist/runtime-context-manifest.js.map +1 -0
- package/dist/runtime-execution-renderer.d.ts +3 -1
- package/dist/runtime-execution-renderer.js +17 -53
- package/dist/runtime-execution-renderer.js.map +1 -1
- package/dist/runtime-execution.d.ts +2 -1
- package/dist/runtime-execution.js +166 -4
- package/dist/runtime-execution.js.map +1 -1
- package/dist/runtime-guardrails.js +9 -1
- package/dist/runtime-guardrails.js.map +1 -1
- package/dist/runtime-lifecycle-watch.d.ts +93 -0
- package/dist/runtime-lifecycle-watch.js +391 -0
- package/dist/runtime-lifecycle-watch.js.map +1 -0
- package/dist/runtime-parent-actions.d.ts +7 -2
- package/dist/runtime-parent-actions.js +132 -1
- package/dist/runtime-parent-actions.js.map +1 -1
- package/dist/runtime-renderer-lines.d.ts +5 -0
- package/dist/runtime-renderer-lines.js +58 -0
- package/dist/runtime-renderer-lines.js.map +1 -0
- package/dist/runtime-spawn-bridge.js +40 -10
- package/dist/runtime-spawn-bridge.js.map +1 -1
- package/dist/runtime-spawn-quality.d.ts +2 -0
- package/dist/runtime-spawn-quality.js +11 -0
- package/dist/runtime-spawn-quality.js.map +1 -0
- package/dist/sonar-insights.d.ts +1 -0
- package/dist/sonar-insights.js +6 -2
- package/dist/sonar-insights.js.map +1 -1
- package/dist/types/model-config.d.ts +6 -0
- package/dist/types/runtime.d.ts +26 -2
- package/dist/types/tasks.d.ts +12 -0
- package/dist/types.d.ts +1 -1
- package/dist/types.js.map +1 -1
- package/dist/web-api.js +8 -0
- package/dist/web-api.js.map +1 -1
- package/dist/web-console/assets/index-DXbrxR_d.js +11 -0
- package/dist/web-console/index.html +1 -1
- package/dist/workflow-handoff-assessment.d.ts +3 -0
- package/dist/workflow-handoff-assessment.js +246 -0
- package/dist/workflow-handoff-assessment.js.map +1 -0
- package/dist/workflow-handoff-contract.d.ts +32 -0
- package/dist/workflow-handoff-contract.js +123 -0
- package/dist/workflow-handoff-contract.js.map +1 -0
- package/dist/workflow-phase-transition.d.ts +16 -0
- package/dist/workflow-phase-transition.js +76 -0
- package/dist/workflow-phase-transition.js.map +1 -0
- package/dist/workflow-run-commands.js +47 -12
- package/dist/workflow-run-commands.js.map +1 -1
- package/dist/workflow-services.js +57 -27
- package/dist/workflow-services.js.map +1 -1
- package/dist/workspace-init-artifacts.d.ts +17 -0
- package/dist/workspace-init-artifacts.js +81 -0
- package/dist/workspace-init-artifacts.js.map +1 -0
- package/dist/workspace-runtime-bootstrap.d.ts +12 -0
- package/dist/workspace-runtime-bootstrap.js +64 -0
- package/dist/workspace-runtime-bootstrap.js.map +1 -0
- package/dist/workspace.d.ts +5 -2
- package/dist/workspace.js +43 -145
- package/dist/workspace.js.map +1 -1
- package/docs/architecture-debt-inventory.md +25 -0
- package/docs/autonomous-workflow.md +7 -0
- package/docs/e2e-test-batteries.md +106 -0
- package/docs/orchestra-mvp.md +8 -0
- package/docs/release-test-matrix.md +7 -0
- package/docs/runtime-adapters.md +86 -9
- package/docs/site-manifest.json +2 -0
- package/docs/sonar-quality-gates.md +133 -11
- package/package.json +5 -1
- package/rules/delivery-quality-gates.mdc +6 -0
- package/rules/devops-tooling.mdc +1 -0
- package/rules/security-guardrails.mdc +3 -0
- package/rules/testing-discipline.mdc +9 -0
- package/dist/web-console/assets/index-CgSKcay8.js +0 -11
|
@@ -0,0 +1,463 @@
|
|
|
1
|
+
const GENERIC_CONTRACT = {
|
|
2
|
+
id: "generic-advisory",
|
|
3
|
+
appliesToRoles: ["*"],
|
|
4
|
+
capabilities: [],
|
|
5
|
+
requiredInputs: ["task goal", "acceptance criteria"],
|
|
6
|
+
requiredContextFiles: [],
|
|
7
|
+
requiredOutputs: [
|
|
8
|
+
requirement("handoff-notes", "Handoff notes", ["handoff", "summary"]),
|
|
9
|
+
],
|
|
10
|
+
requiredEvidence: [],
|
|
11
|
+
blockingConditions: [],
|
|
12
|
+
allowedTransitions: ["*"],
|
|
13
|
+
validationMode: "advisory",
|
|
14
|
+
domainOverrides: [regulatedDomainOverride()],
|
|
15
|
+
};
|
|
16
|
+
export const QUALITY_CONTRACT_REGISTRY = [
|
|
17
|
+
{
|
|
18
|
+
id: "developer-delivery",
|
|
19
|
+
appliesToRoles: ["developer"],
|
|
20
|
+
capabilities: ["implementation", "code", "test", "qa-evidence"],
|
|
21
|
+
requiredInputs: ["task goal", "acceptance criteria", "architecture notes"],
|
|
22
|
+
requiredContextFiles: [
|
|
23
|
+
"AGENTS.md",
|
|
24
|
+
"rules/development-engineering.mdc",
|
|
25
|
+
"rules/testing-discipline.mdc",
|
|
26
|
+
],
|
|
27
|
+
requiredOutputs: [
|
|
28
|
+
requirement("consumed-context", "Consumed context files", [
|
|
29
|
+
"consumed context files",
|
|
30
|
+
"context files",
|
|
31
|
+
]),
|
|
32
|
+
requirement("changed-files", "Changed files", [
|
|
33
|
+
"changed files",
|
|
34
|
+
"changed components",
|
|
35
|
+
"touched files",
|
|
36
|
+
"modified files",
|
|
37
|
+
]),
|
|
38
|
+
requirement("architectural-concerns", "Architectural concerns", [
|
|
39
|
+
"architectural concerns",
|
|
40
|
+
"inherited",
|
|
41
|
+
"self-imposed",
|
|
42
|
+
]),
|
|
43
|
+
requirement("handoff-notes", "Handoff notes", ["handoff", "summary"]),
|
|
44
|
+
],
|
|
45
|
+
requiredEvidence: [
|
|
46
|
+
requirement("unit-tests", "Unit test evidence", [
|
|
47
|
+
"unit test",
|
|
48
|
+
"node --test",
|
|
49
|
+
"npm test",
|
|
50
|
+
"mocha",
|
|
51
|
+
]),
|
|
52
|
+
requirement("command-evidence", "Command evidence", [
|
|
53
|
+
"commands run",
|
|
54
|
+
"npm run",
|
|
55
|
+
"node ",
|
|
56
|
+
"build",
|
|
57
|
+
"lint",
|
|
58
|
+
]),
|
|
59
|
+
],
|
|
60
|
+
blockingConditions: [
|
|
61
|
+
"No consumed context acknowledgement",
|
|
62
|
+
"No unit test or command evidence",
|
|
63
|
+
],
|
|
64
|
+
allowedTransitions: ["qa", "ux_review", "security_review", "done"],
|
|
65
|
+
returnToPhase: "developer",
|
|
66
|
+
validationMode: "block",
|
|
67
|
+
domainOverrides: [regulatedDomainOverride()],
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
id: "qa-verification",
|
|
71
|
+
appliesToRoles: ["qa", "sdet"],
|
|
72
|
+
capabilities: ["qa-evidence", "testing", "automation"],
|
|
73
|
+
requiredInputs: ["acceptance criteria", "developer handoff", "test plan"],
|
|
74
|
+
requiredContextFiles: [
|
|
75
|
+
"AGENTS.md",
|
|
76
|
+
"rules/testing-discipline.mdc",
|
|
77
|
+
"rules/delivery-quality-gates.mdc",
|
|
78
|
+
],
|
|
79
|
+
requiredOutputs: [
|
|
80
|
+
requirement("consumed-context", "Consumed context files", [
|
|
81
|
+
"consumed context files",
|
|
82
|
+
"context files",
|
|
83
|
+
]),
|
|
84
|
+
requirement("acceptance-mapping", "Acceptance criteria mapping", [
|
|
85
|
+
"acceptance criteria coverage",
|
|
86
|
+
"acceptance criteria mapping",
|
|
87
|
+
"ac1",
|
|
88
|
+
"ac-to-evidence",
|
|
89
|
+
]),
|
|
90
|
+
requirement("actual-results", "Actual result evidence", [
|
|
91
|
+
"actual result",
|
|
92
|
+
"results",
|
|
93
|
+
"pass",
|
|
94
|
+
"fail",
|
|
95
|
+
]),
|
|
96
|
+
requirement("edge-cases", "Edge cases", [
|
|
97
|
+
"edge case",
|
|
98
|
+
"boundary",
|
|
99
|
+
"negative case",
|
|
100
|
+
]),
|
|
101
|
+
requirement("release-recommendation", "Release recommendation", [
|
|
102
|
+
"release recommendation",
|
|
103
|
+
"recommendation",
|
|
104
|
+
"go/no-go",
|
|
105
|
+
"go no-go",
|
|
106
|
+
]),
|
|
107
|
+
],
|
|
108
|
+
requiredEvidence: [
|
|
109
|
+
requirement("evidence-artifacts", "Evidence artifacts", [
|
|
110
|
+
"evidence",
|
|
111
|
+
"screenshot",
|
|
112
|
+
"trace",
|
|
113
|
+
"video",
|
|
114
|
+
"command",
|
|
115
|
+
"log",
|
|
116
|
+
]),
|
|
117
|
+
],
|
|
118
|
+
blockingConditions: [
|
|
119
|
+
"No acceptance criteria mapping",
|
|
120
|
+
"No actual result evidence",
|
|
121
|
+
"No release recommendation",
|
|
122
|
+
],
|
|
123
|
+
allowedTransitions: ["release", "developer"],
|
|
124
|
+
returnToPhase: "developer",
|
|
125
|
+
validationMode: "block",
|
|
126
|
+
domainOverrides: [regulatedDomainOverride()],
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
id: "release-readiness",
|
|
130
|
+
appliesToRoles: ["release_manager"],
|
|
131
|
+
capabilities: ["release", "deployment", "rollback"],
|
|
132
|
+
requiredInputs: ["QA evidence", "accepted risks", "release notes"],
|
|
133
|
+
requiredContextFiles: [
|
|
134
|
+
"AGENTS.md",
|
|
135
|
+
"rules/delivery-quality-gates.mdc",
|
|
136
|
+
"rules/release-rollback.mdc",
|
|
137
|
+
],
|
|
138
|
+
requiredOutputs: [
|
|
139
|
+
requirement("consumed-context", "Consumed context files", [
|
|
140
|
+
"consumed context files",
|
|
141
|
+
"context files",
|
|
142
|
+
]),
|
|
143
|
+
requirement("qa-review", "QA evidence review", [
|
|
144
|
+
"qa evidence",
|
|
145
|
+
"test evidence",
|
|
146
|
+
"evidence review",
|
|
147
|
+
]),
|
|
148
|
+
requirement("go-no-go", "Go/no-go", ["go/no-go", "go no-go", "no-go"]),
|
|
149
|
+
requirement("rollback-risk", "Rollback risk", [
|
|
150
|
+
"rollback",
|
|
151
|
+
"rollback risk",
|
|
152
|
+
]),
|
|
153
|
+
requirement("docs-changelog", "Docs or changelog decision", [
|
|
154
|
+
"docs",
|
|
155
|
+
"documentation",
|
|
156
|
+
"changelog",
|
|
157
|
+
"release notes",
|
|
158
|
+
]),
|
|
159
|
+
requirement("residual-risk", "Residual risk", [
|
|
160
|
+
"residual risk",
|
|
161
|
+
"accepted risk",
|
|
162
|
+
"remaining risk",
|
|
163
|
+
]),
|
|
164
|
+
],
|
|
165
|
+
requiredEvidence: [],
|
|
166
|
+
blockingConditions: ["No go/no-go", "No rollback risk review"],
|
|
167
|
+
allowedTransitions: ["done", "qa"],
|
|
168
|
+
returnToPhase: "qa",
|
|
169
|
+
validationMode: "block",
|
|
170
|
+
domainOverrides: [regulatedDomainOverride()],
|
|
171
|
+
},
|
|
172
|
+
];
|
|
173
|
+
export function resolveQualityContract(input) {
|
|
174
|
+
const roleId = roleIdFor(input.role);
|
|
175
|
+
const capabilities = capabilitiesFor(input.role);
|
|
176
|
+
const taskText = taskSearchText(input.task);
|
|
177
|
+
const roleContract = QUALITY_CONTRACT_REGISTRY.find((candidate) => candidate.appliesToRoles.includes(roleId));
|
|
178
|
+
const contract = roleContract ?? GENERIC_CONTRACT;
|
|
179
|
+
return applyQualityContractOverrides({
|
|
180
|
+
contract,
|
|
181
|
+
input,
|
|
182
|
+
roleId,
|
|
183
|
+
capabilities,
|
|
184
|
+
taskText,
|
|
185
|
+
isUnknownRole: !roleContract,
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
export function evaluateQualityContract(input) {
|
|
189
|
+
const contract = resolveQualityContract(input);
|
|
190
|
+
const haystack = normalize([
|
|
191
|
+
input.handoffContent,
|
|
192
|
+
input.output?.summary,
|
|
193
|
+
input.output?.notes,
|
|
194
|
+
input.output?.handoff,
|
|
195
|
+
...(input.output?.findings ?? []),
|
|
196
|
+
...(input.output?.decisions ?? []),
|
|
197
|
+
...(input.output?.evidence ?? []),
|
|
198
|
+
input.handoff?.changed,
|
|
199
|
+
input.handoff?.behavior,
|
|
200
|
+
input.handoff?.tests,
|
|
201
|
+
input.handoff?.commands,
|
|
202
|
+
input.output?.architecturalConcerns
|
|
203
|
+
? [
|
|
204
|
+
"architectural concerns",
|
|
205
|
+
...input.output.architecturalConcerns.inherited,
|
|
206
|
+
...input.output.architecturalConcerns.selfImposed,
|
|
207
|
+
].join(" ")
|
|
208
|
+
: undefined,
|
|
209
|
+
]
|
|
210
|
+
.filter(Boolean)
|
|
211
|
+
.join(" "));
|
|
212
|
+
const assessments = [
|
|
213
|
+
...contract.requiredOutputs,
|
|
214
|
+
...contract.requiredEvidence,
|
|
215
|
+
].map((expected) => assessRequirement(expected, haystack));
|
|
216
|
+
const contextAssessment = assessContextAcknowledgement(input, contract);
|
|
217
|
+
if (contextAssessment)
|
|
218
|
+
assessments.unshift(contextAssessment);
|
|
219
|
+
const transitionAssessment = assessAllowedTransition(input, contract);
|
|
220
|
+
if (transitionAssessment)
|
|
221
|
+
assessments.unshift(transitionAssessment);
|
|
222
|
+
const blockingGaps = assessments.filter((assessment) => assessment.status === "gap" && shouldBlock(contract, assessment));
|
|
223
|
+
const warnGaps = assessments.filter((assessment) => assessment.status === "gap" && !shouldBlock(contract, assessment));
|
|
224
|
+
const status = blockingGaps.length > 0 || contract.validationMode === "human_approval"
|
|
225
|
+
? "block"
|
|
226
|
+
: warnGaps.length > 0
|
|
227
|
+
? "warn"
|
|
228
|
+
: "pass";
|
|
229
|
+
return {
|
|
230
|
+
contract,
|
|
231
|
+
status,
|
|
232
|
+
mode: contract.validationMode,
|
|
233
|
+
requiresHumanApproval: contract.validationMode === "human_approval",
|
|
234
|
+
transitionAllowed: transitionAssessment?.status !== "gap",
|
|
235
|
+
allowedTransitions: contract.allowedTransitions.slice(),
|
|
236
|
+
assessments,
|
|
237
|
+
missingRequirements: assessments
|
|
238
|
+
.filter((assessment) => assessment.status === "gap")
|
|
239
|
+
.map((assessment) => assessment.label),
|
|
240
|
+
...(status === "block" && contract.returnToPhase
|
|
241
|
+
? { returnToPhase: contract.returnToPhase }
|
|
242
|
+
: {}),
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
function assessAllowedTransition(input, contract) {
|
|
246
|
+
if (!input.nextPhase || contract.allowedTransitions.includes("*")) {
|
|
247
|
+
return undefined;
|
|
248
|
+
}
|
|
249
|
+
if (contract.allowedTransitions.includes(input.nextPhase)) {
|
|
250
|
+
return {
|
|
251
|
+
id: "allowed-transition",
|
|
252
|
+
label: "Allowed phase transition",
|
|
253
|
+
status: "covered",
|
|
254
|
+
severity: "block",
|
|
255
|
+
detail: `${input.phase ?? "phase"} can transition to ${input.nextPhase}.`,
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
return {
|
|
259
|
+
id: "allowed-transition",
|
|
260
|
+
label: "Allowed phase transition",
|
|
261
|
+
status: "gap",
|
|
262
|
+
severity: "block",
|
|
263
|
+
detail: `Gap: ${input.phase ?? "phase"} cannot transition to ${input.nextPhase}; allowed transitions are ${contract.allowedTransitions.join(", ")}.`,
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
function requirement(id, label, match, severity = "block") {
|
|
267
|
+
return { id, label, match, severity };
|
|
268
|
+
}
|
|
269
|
+
function regulatedDomainOverride() {
|
|
270
|
+
return {
|
|
271
|
+
signals: [
|
|
272
|
+
"regulated",
|
|
273
|
+
"medical",
|
|
274
|
+
"medicine",
|
|
275
|
+
"healthcare",
|
|
276
|
+
"hipaa",
|
|
277
|
+
"pii",
|
|
278
|
+
"payment",
|
|
279
|
+
"pci",
|
|
280
|
+
"finance",
|
|
281
|
+
"sox",
|
|
282
|
+
],
|
|
283
|
+
validationMode: "human_approval",
|
|
284
|
+
requiresHumanApproval: true,
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
function roleIdFor(role) {
|
|
288
|
+
return typeof role === "string" ? role : role.id;
|
|
289
|
+
}
|
|
290
|
+
function capabilitiesFor(role) {
|
|
291
|
+
return typeof role === "string" ? [] : role.capabilities;
|
|
292
|
+
}
|
|
293
|
+
function taskSearchText(task) {
|
|
294
|
+
return normalize([
|
|
295
|
+
task?.title,
|
|
296
|
+
task?.goal,
|
|
297
|
+
task?.scope,
|
|
298
|
+
...(task?.paths ?? []),
|
|
299
|
+
...(task?.risks ?? []),
|
|
300
|
+
]
|
|
301
|
+
.filter(Boolean)
|
|
302
|
+
.join(" "));
|
|
303
|
+
}
|
|
304
|
+
function applyQualityContractOverrides({ contract, input, roleId, capabilities, taskText, isUnknownRole, }) {
|
|
305
|
+
const configured = input.qualityContracts;
|
|
306
|
+
let resolved = cloneContract(contract);
|
|
307
|
+
resolved = applyDomainOverride(resolved, taskText);
|
|
308
|
+
resolved = applyConfiguredMode(resolved, configured?.validationMode);
|
|
309
|
+
if (isUnknownRole) {
|
|
310
|
+
resolved = applyConfiguredMode(resolved, configured?.unknownRoleMode);
|
|
311
|
+
}
|
|
312
|
+
for (const capability of capabilities) {
|
|
313
|
+
resolved = applyConfiguredOverride(resolved, configured?.capabilityOverrides?.[capability]);
|
|
314
|
+
}
|
|
315
|
+
resolved = applyConfiguredOverride(resolved, configured?.roleOverrides?.[roleId]);
|
|
316
|
+
if (input.phase) {
|
|
317
|
+
resolved = applyConfiguredOverride(resolved, configured?.phaseOverrides?.[input.phase]);
|
|
318
|
+
}
|
|
319
|
+
resolved = applyTransitionOverride(resolved, input, configured);
|
|
320
|
+
resolved = applyConfiguredDomainOverride(resolved, taskText, configured?.domainOverrides);
|
|
321
|
+
return applyQualityModeOverride(resolved, input.qualityMode);
|
|
322
|
+
}
|
|
323
|
+
function applyDomainOverride(contract, taskText) {
|
|
324
|
+
const override = contract.domainOverrides.find((candidate) => candidate.signals.some((signal) => taskText.includes(normalize(signal))));
|
|
325
|
+
if (!override)
|
|
326
|
+
return cloneContract(contract);
|
|
327
|
+
return {
|
|
328
|
+
...cloneContract(contract),
|
|
329
|
+
validationMode: override.validationMode,
|
|
330
|
+
};
|
|
331
|
+
}
|
|
332
|
+
function applyConfiguredDomainOverride(contract, taskText, overrides) {
|
|
333
|
+
const override = overrides?.find((candidate) => candidate.signals.some((signal) => taskText.includes(normalize(signal))));
|
|
334
|
+
if (!override)
|
|
335
|
+
return contract;
|
|
336
|
+
return { ...contract, validationMode: override.validationMode };
|
|
337
|
+
}
|
|
338
|
+
function applyConfiguredMode(contract, mode) {
|
|
339
|
+
return mode
|
|
340
|
+
? applyConfiguredOverride(contract, { validationMode: mode })
|
|
341
|
+
: contract;
|
|
342
|
+
}
|
|
343
|
+
function applyConfiguredOverride(contract, override) {
|
|
344
|
+
if (!override)
|
|
345
|
+
return contract;
|
|
346
|
+
return {
|
|
347
|
+
...contract,
|
|
348
|
+
...(override.validationMode
|
|
349
|
+
? { validationMode: override.validationMode }
|
|
350
|
+
: {}),
|
|
351
|
+
...(override.allowedTransitions
|
|
352
|
+
? { allowedTransitions: override.allowedTransitions.slice() }
|
|
353
|
+
: {}),
|
|
354
|
+
...(override.returnToPhase
|
|
355
|
+
? { returnToPhase: override.returnToPhase }
|
|
356
|
+
: {}),
|
|
357
|
+
};
|
|
358
|
+
}
|
|
359
|
+
function applyTransitionOverride(contract, input, config) {
|
|
360
|
+
if (!input.phase || !input.nextPhase)
|
|
361
|
+
return contract;
|
|
362
|
+
const override = transitionOverrideFor(config, input.phase, input.nextPhase);
|
|
363
|
+
if (!override)
|
|
364
|
+
return contract;
|
|
365
|
+
const allowedTransitions = override.allowedTransitions ??
|
|
366
|
+
(override.allowed === true
|
|
367
|
+
? uniqueStrings([...contract.allowedTransitions, input.nextPhase])
|
|
368
|
+
: override.allowed === false
|
|
369
|
+
? contract.allowedTransitions.filter((phase) => phase !== input.nextPhase)
|
|
370
|
+
: undefined);
|
|
371
|
+
return applyConfiguredOverride(contract, {
|
|
372
|
+
...override,
|
|
373
|
+
...(allowedTransitions ? { allowedTransitions } : {}),
|
|
374
|
+
});
|
|
375
|
+
}
|
|
376
|
+
function transitionOverrideFor(config, phase, nextPhase) {
|
|
377
|
+
const overrides = config?.transitionOverrides;
|
|
378
|
+
if (!overrides)
|
|
379
|
+
return undefined;
|
|
380
|
+
return (overrides[`${phase}->${nextPhase}`] ??
|
|
381
|
+
overrides[`${phase}→${nextPhase}`] ??
|
|
382
|
+
overrides[phase]);
|
|
383
|
+
}
|
|
384
|
+
function applyQualityModeOverride(contract, mode) {
|
|
385
|
+
if (!mode)
|
|
386
|
+
return contract;
|
|
387
|
+
return { ...contract, validationMode: mode };
|
|
388
|
+
}
|
|
389
|
+
function assessRequirement(requirement, haystack) {
|
|
390
|
+
const covered = requirement.match.some((token) => haystack.includes(normalize(token)));
|
|
391
|
+
return {
|
|
392
|
+
id: requirement.id,
|
|
393
|
+
label: requirement.label,
|
|
394
|
+
status: covered ? "covered" : "gap",
|
|
395
|
+
severity: requirement.severity,
|
|
396
|
+
detail: covered
|
|
397
|
+
? `${requirement.label} covered.`
|
|
398
|
+
: `Gap: ${requirement.label} missing.`,
|
|
399
|
+
};
|
|
400
|
+
}
|
|
401
|
+
function assessContextAcknowledgement(input, contract) {
|
|
402
|
+
if (contract.requiredContextFiles.length === 0)
|
|
403
|
+
return undefined;
|
|
404
|
+
if (input.contextAcknowledgement?.status === "pass") {
|
|
405
|
+
return {
|
|
406
|
+
id: "context-acknowledgement",
|
|
407
|
+
label: "Required context acknowledgement",
|
|
408
|
+
status: "covered",
|
|
409
|
+
severity: "block",
|
|
410
|
+
detail: "Required context acknowledgement passed.",
|
|
411
|
+
};
|
|
412
|
+
}
|
|
413
|
+
const haystack = normalize([input.handoffContent, input.output?.handoff].filter(Boolean).join(" "));
|
|
414
|
+
if (haystack.includes("consumed context files")) {
|
|
415
|
+
return {
|
|
416
|
+
id: "context-acknowledgement",
|
|
417
|
+
label: "Required context acknowledgement",
|
|
418
|
+
status: "covered",
|
|
419
|
+
severity: "block",
|
|
420
|
+
detail: "Consumed context files section was provided.",
|
|
421
|
+
};
|
|
422
|
+
}
|
|
423
|
+
return {
|
|
424
|
+
id: "context-acknowledgement",
|
|
425
|
+
label: "Required context acknowledgement",
|
|
426
|
+
status: "gap",
|
|
427
|
+
severity: "block",
|
|
428
|
+
detail: "Gap: required context acknowledgement missing.",
|
|
429
|
+
};
|
|
430
|
+
}
|
|
431
|
+
function shouldBlock(contract, assessment) {
|
|
432
|
+
return contract.validationMode === "block" ||
|
|
433
|
+
contract.validationMode === "human_approval"
|
|
434
|
+
? assessment.severity === "block"
|
|
435
|
+
: false;
|
|
436
|
+
}
|
|
437
|
+
function cloneContract(contract) {
|
|
438
|
+
return {
|
|
439
|
+
...contract,
|
|
440
|
+
appliesToRoles: contract.appliesToRoles.slice(),
|
|
441
|
+
capabilities: contract.capabilities.slice(),
|
|
442
|
+
requiredInputs: contract.requiredInputs.slice(),
|
|
443
|
+
requiredContextFiles: contract.requiredContextFiles.slice(),
|
|
444
|
+
requiredOutputs: contract.requiredOutputs.map((item) => ({ ...item })),
|
|
445
|
+
requiredEvidence: contract.requiredEvidence.map((item) => ({ ...item })),
|
|
446
|
+
blockingConditions: contract.blockingConditions.slice(),
|
|
447
|
+
allowedTransitions: contract.allowedTransitions.slice(),
|
|
448
|
+
domainOverrides: contract.domainOverrides.map((item) => ({
|
|
449
|
+
...item,
|
|
450
|
+
signals: item.signals.slice(),
|
|
451
|
+
})),
|
|
452
|
+
};
|
|
453
|
+
}
|
|
454
|
+
function normalize(value) {
|
|
455
|
+
return value
|
|
456
|
+
.toLowerCase()
|
|
457
|
+
.replace(/[^a-z0-9]+/g, " ")
|
|
458
|
+
.trim();
|
|
459
|
+
}
|
|
460
|
+
function uniqueStrings(values) {
|
|
461
|
+
return [...new Set(values.map((value) => value.trim()).filter(Boolean))];
|
|
462
|
+
}
|
|
463
|
+
//# sourceMappingURL=quality-contracts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"quality-contracts.js","sourceRoot":"","sources":["../src/quality-contracts.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { readFile, writeFile } from "node:fs/promises";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { DEFAULT_PHASE_PLAYBOOKS, DEFAULT_PLAYBOOKS_DIR, } from "./phase-playbooks.js";
|
|
4
|
-
import {
|
|
5
|
-
import { listRuntimeAdapters } from "./runtime-adapters.js";
|
|
4
|
+
import { resolveWorkspaceWritePath } from "./fs-utils.js";
|
|
6
5
|
import { renderRuntimeBootstrap, upsertRuntimeBootstrapBlock, } from "./runtime-bootstrap.js";
|
|
6
|
+
import { resolveRefreshRuntimeBootstrapTargets } from "./runtime-bootstrap-targets.js";
|
|
7
|
+
import { backupExistingWorkspaceFiles } from "./workspace-init-artifacts.js";
|
|
7
8
|
export async function refreshGeneratedFiles({ root = process.cwd(), check = false, dryRun = false, force = false, targets, } = {}) {
|
|
8
9
|
const items = [
|
|
9
10
|
...(await refreshRuntimeBootstrapFiles({
|
|
@@ -15,8 +16,9 @@ export async function refreshGeneratedFiles({ root = process.cwd(), check = fals
|
|
|
15
16
|
})),
|
|
16
17
|
...(await refreshPhasePlaybooks({ root, check, dryRun, force })),
|
|
17
18
|
];
|
|
19
|
+
const mode = refreshMode({ check, dryRun });
|
|
18
20
|
return {
|
|
19
|
-
mode
|
|
21
|
+
mode,
|
|
20
22
|
force,
|
|
21
23
|
driftStatus: driftStatus(items),
|
|
22
24
|
items,
|
|
@@ -54,24 +56,25 @@ async function refreshRuntimeBootstrapFiles({ root, check, dryRun, force, target
|
|
|
54
56
|
}
|
|
55
57
|
if (result.changed && !check && !dryRun) {
|
|
56
58
|
await ensureParent(filePath);
|
|
59
|
+
await backupExistingWorkspaceFiles({
|
|
60
|
+
root,
|
|
61
|
+
relativePaths: [candidate.path],
|
|
62
|
+
});
|
|
57
63
|
await writeFile(filePath, result.content, "utf8");
|
|
58
64
|
}
|
|
59
65
|
const beforeStatus = runtimeBeforeStatus(existing, result);
|
|
66
|
+
const changed = result.changed;
|
|
60
67
|
items.push({
|
|
61
68
|
kind: "runtime-bootstrap",
|
|
62
69
|
path: candidate.path,
|
|
63
70
|
target: candidate.target,
|
|
64
71
|
managedBlockId: `runtime-bootstrap:${candidate.target}`,
|
|
65
72
|
beforeStatus,
|
|
66
|
-
afterStatus: afterStatus(
|
|
67
|
-
status:
|
|
68
|
-
reason: result
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
? "managed block refreshed"
|
|
72
|
-
: "managed block current",
|
|
73
|
-
plannedWrite: result.changed && !check,
|
|
74
|
-
recommendedCommand: result.changed
|
|
73
|
+
afterStatus: afterStatus(changed, check, dryRun),
|
|
74
|
+
status: itemStatus(changed),
|
|
75
|
+
reason: runtimeRefreshReason(result),
|
|
76
|
+
plannedWrite: changed && !check,
|
|
77
|
+
recommendedCommand: changed
|
|
75
78
|
? recommendedRefreshCommand({ force, target: candidate.target })
|
|
76
79
|
: "none",
|
|
77
80
|
});
|
|
@@ -79,21 +82,10 @@ async function refreshRuntimeBootstrapFiles({ root, check, dryRun, force, target
|
|
|
79
82
|
return items;
|
|
80
83
|
}
|
|
81
84
|
async function existingRuntimeBootstrapTargets(root, targets) {
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
path: file,
|
|
87
|
-
target: adapter.target,
|
|
88
|
-
})));
|
|
89
|
-
const selected = [];
|
|
90
|
-
for (const candidate of candidates) {
|
|
91
|
-
const filePath = resolveWorkspaceWritePath(root, candidate.path);
|
|
92
|
-
if (defaults.has(candidate.path) || (await exists(filePath))) {
|
|
93
|
-
selected.push(candidate);
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
return selected;
|
|
85
|
+
return (await resolveRefreshRuntimeBootstrapTargets({
|
|
86
|
+
root,
|
|
87
|
+
runtimeTargets: targets,
|
|
88
|
+
})).map((item) => ({ path: item.file, target: item.target }));
|
|
97
89
|
}
|
|
98
90
|
async function refreshPhasePlaybooks({ root, check, dryRun, force, }) {
|
|
99
91
|
const items = [];
|
|
@@ -104,8 +96,17 @@ async function refreshPhasePlaybooks({ root, check, dryRun, force, }) {
|
|
|
104
96
|
const desired = `${content}\n`;
|
|
105
97
|
const missing = existing === "";
|
|
106
98
|
const changed = missing || (force && existing !== desired);
|
|
99
|
+
const beforeStatus = phasePlaybookBeforeStatus({
|
|
100
|
+
missing,
|
|
101
|
+
existing,
|
|
102
|
+
desired,
|
|
103
|
+
});
|
|
107
104
|
if (changed && !check && !dryRun) {
|
|
108
105
|
await ensureParent(filePath);
|
|
106
|
+
await backupExistingWorkspaceFiles({
|
|
107
|
+
root,
|
|
108
|
+
relativePaths: [relativePath],
|
|
109
|
+
});
|
|
109
110
|
await writeFile(filePath, desired, "utf8");
|
|
110
111
|
}
|
|
111
112
|
items.push({
|
|
@@ -113,30 +114,71 @@ async function refreshPhasePlaybooks({ root, check, dryRun, force, }) {
|
|
|
113
114
|
path: relativePath,
|
|
114
115
|
target: phase,
|
|
115
116
|
managedBlockId: `phase-playbook:${phase}`,
|
|
116
|
-
beforeStatus
|
|
117
|
-
? "missing"
|
|
118
|
-
: existing === desired
|
|
119
|
-
? "current"
|
|
120
|
-
: "custom",
|
|
117
|
+
beforeStatus,
|
|
121
118
|
afterStatus: afterStatus(changed, check, dryRun),
|
|
122
|
-
status: changed
|
|
123
|
-
reason: missing
|
|
124
|
-
? "default playbook missing"
|
|
125
|
-
: changed
|
|
126
|
-
? "default playbook refreshed with --force"
|
|
127
|
-
: force
|
|
128
|
-
? "default playbook current"
|
|
129
|
-
: "existing playbook preserved",
|
|
119
|
+
status: itemStatus(changed),
|
|
120
|
+
reason: phasePlaybookRefreshReason({ missing, changed, force }),
|
|
130
121
|
plannedWrite: changed && !check,
|
|
131
|
-
recommendedCommand:
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
122
|
+
recommendedCommand: phasePlaybookRecommendedCommand({
|
|
123
|
+
missing,
|
|
124
|
+
changed,
|
|
125
|
+
force,
|
|
126
|
+
}),
|
|
136
127
|
});
|
|
137
128
|
}
|
|
138
129
|
return items;
|
|
139
130
|
}
|
|
131
|
+
function refreshMode({ check, dryRun, }) {
|
|
132
|
+
if (check) {
|
|
133
|
+
return "check";
|
|
134
|
+
}
|
|
135
|
+
if (dryRun) {
|
|
136
|
+
return "dry-run";
|
|
137
|
+
}
|
|
138
|
+
return "apply";
|
|
139
|
+
}
|
|
140
|
+
function itemStatus(changed) {
|
|
141
|
+
return changed ? "changed" : "unchanged";
|
|
142
|
+
}
|
|
143
|
+
function runtimeRefreshReason(result) {
|
|
144
|
+
if (result.missing) {
|
|
145
|
+
return "managed block missing";
|
|
146
|
+
}
|
|
147
|
+
if (result.changed) {
|
|
148
|
+
return "managed block refreshed";
|
|
149
|
+
}
|
|
150
|
+
return "managed block current";
|
|
151
|
+
}
|
|
152
|
+
function phasePlaybookBeforeStatus({ missing, existing, desired, }) {
|
|
153
|
+
if (missing) {
|
|
154
|
+
return "missing";
|
|
155
|
+
}
|
|
156
|
+
if (existing === desired) {
|
|
157
|
+
return "current";
|
|
158
|
+
}
|
|
159
|
+
return "custom";
|
|
160
|
+
}
|
|
161
|
+
function phasePlaybookRefreshReason({ missing, changed, force, }) {
|
|
162
|
+
if (missing) {
|
|
163
|
+
return "default playbook missing";
|
|
164
|
+
}
|
|
165
|
+
if (changed) {
|
|
166
|
+
return "default playbook refreshed with --force";
|
|
167
|
+
}
|
|
168
|
+
if (force) {
|
|
169
|
+
return "default playbook current";
|
|
170
|
+
}
|
|
171
|
+
return "existing playbook preserved";
|
|
172
|
+
}
|
|
173
|
+
function phasePlaybookRecommendedCommand({ missing, changed, force, }) {
|
|
174
|
+
if (changed) {
|
|
175
|
+
return recommendedRefreshCommand({ force });
|
|
176
|
+
}
|
|
177
|
+
if (missing) {
|
|
178
|
+
return recommendedRefreshCommand({ force: false });
|
|
179
|
+
}
|
|
180
|
+
return "none";
|
|
181
|
+
}
|
|
140
182
|
function runtimeBeforeStatus(existing, result) {
|
|
141
183
|
if (existing === "") {
|
|
142
184
|
return "missing";
|