@mcoda/core 0.1.18 → 0.1.20

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.
Files changed (58) hide show
  1. package/dist/api/QaTasksApi.d.ts.map +1 -1
  2. package/dist/api/QaTasksApi.js +3 -0
  3. package/dist/prompts/PdrPrompts.d.ts.map +1 -1
  4. package/dist/prompts/PdrPrompts.js +22 -8
  5. package/dist/prompts/SdsPrompts.d.ts.map +1 -1
  6. package/dist/prompts/SdsPrompts.js +53 -34
  7. package/dist/services/backlog/BacklogService.d.ts.map +1 -1
  8. package/dist/services/backlog/BacklogService.js +3 -0
  9. package/dist/services/backlog/TaskOrderingService.d.ts +9 -0
  10. package/dist/services/backlog/TaskOrderingService.d.ts.map +1 -1
  11. package/dist/services/backlog/TaskOrderingService.js +251 -35
  12. package/dist/services/docs/DocsService.d.ts.map +1 -1
  13. package/dist/services/docs/DocsService.js +487 -71
  14. package/dist/services/docs/review/gates/PdrFolderTreeGate.d.ts +7 -0
  15. package/dist/services/docs/review/gates/PdrFolderTreeGate.d.ts.map +1 -0
  16. package/dist/services/docs/review/gates/PdrFolderTreeGate.js +151 -0
  17. package/dist/services/docs/review/gates/PdrNoUnresolvedItemsGate.d.ts +7 -0
  18. package/dist/services/docs/review/gates/PdrNoUnresolvedItemsGate.d.ts.map +1 -0
  19. package/dist/services/docs/review/gates/PdrNoUnresolvedItemsGate.js +109 -0
  20. package/dist/services/docs/review/gates/PdrTechStackRationaleGate.d.ts +7 -0
  21. package/dist/services/docs/review/gates/PdrTechStackRationaleGate.d.ts.map +1 -0
  22. package/dist/services/docs/review/gates/PdrTechStackRationaleGate.js +128 -0
  23. package/dist/services/docs/review/gates/SdsFolderTreeGate.d.ts +7 -0
  24. package/dist/services/docs/review/gates/SdsFolderTreeGate.d.ts.map +1 -0
  25. package/dist/services/docs/review/gates/SdsFolderTreeGate.js +153 -0
  26. package/dist/services/docs/review/gates/SdsNoUnresolvedItemsGate.d.ts +7 -0
  27. package/dist/services/docs/review/gates/SdsNoUnresolvedItemsGate.d.ts.map +1 -0
  28. package/dist/services/docs/review/gates/SdsNoUnresolvedItemsGate.js +109 -0
  29. package/dist/services/docs/review/gates/SdsTechStackRationaleGate.d.ts +7 -0
  30. package/dist/services/docs/review/gates/SdsTechStackRationaleGate.d.ts.map +1 -0
  31. package/dist/services/docs/review/gates/SdsTechStackRationaleGate.js +128 -0
  32. package/dist/services/estimate/EstimateService.d.ts +2 -0
  33. package/dist/services/estimate/EstimateService.d.ts.map +1 -1
  34. package/dist/services/estimate/EstimateService.js +54 -0
  35. package/dist/services/execution/QaTasksService.d.ts +6 -0
  36. package/dist/services/execution/QaTasksService.d.ts.map +1 -1
  37. package/dist/services/execution/QaTasksService.js +278 -95
  38. package/dist/services/execution/TaskSelectionService.d.ts +3 -0
  39. package/dist/services/execution/TaskSelectionService.d.ts.map +1 -1
  40. package/dist/services/execution/TaskSelectionService.js +33 -0
  41. package/dist/services/execution/WorkOnTasksService.d.ts +4 -0
  42. package/dist/services/execution/WorkOnTasksService.d.ts.map +1 -1
  43. package/dist/services/execution/WorkOnTasksService.js +146 -22
  44. package/dist/services/openapi/OpenApiService.d.ts.map +1 -1
  45. package/dist/services/openapi/OpenApiService.js +43 -4
  46. package/dist/services/planning/CreateTasksService.d.ts +15 -0
  47. package/dist/services/planning/CreateTasksService.d.ts.map +1 -1
  48. package/dist/services/planning/CreateTasksService.js +592 -81
  49. package/dist/services/planning/RefineTasksService.d.ts +1 -0
  50. package/dist/services/planning/RefineTasksService.d.ts.map +1 -1
  51. package/dist/services/planning/RefineTasksService.js +88 -2
  52. package/dist/services/review/CodeReviewService.d.ts +6 -0
  53. package/dist/services/review/CodeReviewService.d.ts.map +1 -1
  54. package/dist/services/review/CodeReviewService.js +260 -41
  55. package/dist/services/shared/ProjectGuidance.d.ts +18 -2
  56. package/dist/services/shared/ProjectGuidance.d.ts.map +1 -1
  57. package/dist/services/shared/ProjectGuidance.js +535 -34
  58. package/package.json +6 -6
@@ -26,6 +26,7 @@ export interface WorkOnTasksRequest extends TaskSelectionFilters {
26
26
  allowFileOverwrite?: boolean;
27
27
  missingTestsPolicy?: MissingTestsPolicy;
28
28
  allowMissingTests?: boolean;
29
+ executionContextPolicy?: ExecutionContextPolicy;
29
30
  }
30
31
  export interface TaskExecutionResult {
31
32
  taskKey: string;
@@ -41,6 +42,7 @@ export interface WorkOnTasksResult {
41
42
  warnings: string[];
42
43
  }
43
44
  export type MissingTestsPolicy = "block_job" | "skip_task" | "fail_task";
45
+ export type ExecutionContextPolicy = "best_effort" | "require_any" | "require_sds_or_openapi";
44
46
  export declare class WorkOnTasksService {
45
47
  private workspace;
46
48
  private deps;
@@ -79,6 +81,8 @@ export declare class WorkOnTasksService {
79
81
  private logTask;
80
82
  private recordTokenUsage;
81
83
  private updateTaskPhase;
84
+ private enforceExecutionContextPolicy;
85
+ private resolveExecutionPlanningContext;
82
86
  private gatherDocContext;
83
87
  private parseCommentBody;
84
88
  private buildCommentBacklog;
@@ -1 +1 @@
1
- {"version":3,"file":"WorkOnTasksService.d.ts","sourceRoot":"","sources":["../../../src/services/execution/WorkOnTasksService.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"WorkOnTasksService.d.ts","sourceRoot":"","sources":["../../../src/services/execution/WorkOnTasksService.ts"],"names":[],"mappings":"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"}
@@ -834,6 +834,7 @@ const splitFileBlocksByExistence = (fileBlocks, cwd) => {
834
834
  return { existing, remaining };
835
835
  };
836
836
  const DEFAULT_MISSING_TESTS_POLICY = "block_job";
837
+ const DEFAULT_EXECUTION_CONTEXT_POLICY = "best_effort";
837
838
  const normalizeMissingTestsPolicy = (value) => {
838
839
  if (typeof value !== "string")
839
840
  return undefined;
@@ -843,6 +844,15 @@ const normalizeMissingTestsPolicy = (value) => {
843
844
  }
844
845
  return undefined;
845
846
  };
847
+ const normalizeExecutionContextPolicy = (value) => {
848
+ if (typeof value !== "string")
849
+ return undefined;
850
+ const normalized = value.trim().toLowerCase();
851
+ if (normalized === "best_effort" || normalized === "require_any" || normalized === "require_sds_or_openapi") {
852
+ return normalized;
853
+ }
854
+ return undefined;
855
+ };
846
856
  const normalizeStringArray = (value) => {
847
857
  if (!Array.isArray(value))
848
858
  return [];
@@ -1412,6 +1422,15 @@ const allowsTestsOnlyCompletion = (task, metadata, allowedFiles) => {
1412
1422
  return false;
1413
1423
  };
1414
1424
  const hasProductTouchedFiles = (touchedFiles) => touchedFiles.some((file) => !isTestLikePath(file) && !isDocumentationPath(file));
1425
+ const classifyExecutionContextKind = (doc) => {
1426
+ const type = (doc.docType ?? "").toLowerCase();
1427
+ const label = `${doc.path ?? ""} ${doc.title ?? ""}`.toLowerCase();
1428
+ if (type.includes("sds") || /\bsds\b/.test(label))
1429
+ return "sds";
1430
+ if (type.includes("openapi") || type.includes("swagger") || /(openapi|swagger)/.test(label))
1431
+ return "openapi";
1432
+ return "fallback";
1433
+ };
1415
1434
  const buildDocContextQuery = (task, allowedFiles) => {
1416
1435
  const seeds = [
1417
1436
  task.key,
@@ -2260,6 +2279,61 @@ export class WorkOnTasksService {
2260
2279
  await this.logTask(taskRunId, `${phase}:${status}`, phase, payload);
2261
2280
  await this.checkpoint(jobId, `task:${taskKey}:${phase}:${status}`, payload);
2262
2281
  }
2282
+ enforceExecutionContextPolicy(policy, context) {
2283
+ if (policy === "best_effort")
2284
+ return;
2285
+ if (policy === "require_any") {
2286
+ if (!context) {
2287
+ throw new Error("Execution context is required but no planning documents were resolved (policy=require_any).");
2288
+ }
2289
+ return;
2290
+ }
2291
+ if (!context) {
2292
+ throw new Error("Execution context requires SDS/OpenAPI sources, but none were resolved (policy=require_sds_or_openapi).");
2293
+ }
2294
+ if (context.kind !== "sds" && context.kind !== "openapi") {
2295
+ throw new Error(`Execution context policy require_sds_or_openapi rejected source '${context.source}' (kind=${context.kind}).`);
2296
+ }
2297
+ }
2298
+ async resolveExecutionPlanningContext(projectKey, warnings) {
2299
+ if (!projectKey)
2300
+ return undefined;
2301
+ const pickFirst = async (filter) => {
2302
+ const docs = await this.deps.docdex.search(filter);
2303
+ return docs[0];
2304
+ };
2305
+ try {
2306
+ const sdsDoc = await pickFirst({ projectKey, docType: "SDS", profile: "workspace-code" });
2307
+ if (sdsDoc) {
2308
+ return {
2309
+ source: sdsDoc.id ?? sdsDoc.path ?? sdsDoc.title ?? "sds",
2310
+ kind: classifyExecutionContextKind(sdsDoc),
2311
+ };
2312
+ }
2313
+ const openapiDoc = await pickFirst({ projectKey, docType: "OPENAPI", profile: "workspace-code" });
2314
+ if (openapiDoc) {
2315
+ return {
2316
+ source: openapiDoc.id ?? openapiDoc.path ?? openapiDoc.title ?? "openapi",
2317
+ kind: classifyExecutionContextKind(openapiDoc),
2318
+ };
2319
+ }
2320
+ const fallbackDoc = await pickFirst({
2321
+ projectKey,
2322
+ profile: "workspace-code",
2323
+ query: "sds requirements architecture openapi swagger",
2324
+ });
2325
+ if (!fallbackDoc)
2326
+ return undefined;
2327
+ return {
2328
+ source: fallbackDoc.id ?? fallbackDoc.path ?? fallbackDoc.title ?? "workspace-code",
2329
+ kind: classifyExecutionContextKind(fallbackDoc),
2330
+ };
2331
+ }
2332
+ catch (error) {
2333
+ warnings.push(`Execution context preflight failed to query docdex: ${error.message}`);
2334
+ return undefined;
2335
+ }
2336
+ }
2263
2337
  async gatherDocContext(task, projectKey, docLinks = [], allowedFiles = []) {
2264
2338
  const warnings = [];
2265
2339
  const parts = [];
@@ -2286,9 +2360,36 @@ export class WorkOnTasksService {
2286
2360
  }
2287
2361
  }
2288
2362
  try {
2289
- let docs = await this.deps.docdex.search({ projectKey, profile: "workspace-code", query: docQuery });
2363
+ const docs = [];
2364
+ const seen = new Set();
2365
+ const appendDocs = async (filter) => {
2366
+ const found = await this.deps.docdex.search(filter);
2367
+ for (const doc of found) {
2368
+ const key = String(doc.id ?? doc.path ?? doc.title ?? "");
2369
+ if (!key)
2370
+ continue;
2371
+ if (seen.has(key))
2372
+ continue;
2373
+ seen.add(key);
2374
+ docs.push(doc);
2375
+ }
2376
+ };
2377
+ const sdsFilter = docQuery
2378
+ ? { projectKey, docType: "SDS", profile: "workspace-code", query: docQuery }
2379
+ : { projectKey, docType: "SDS", profile: "workspace-code" };
2380
+ const openapiFilter = docQuery
2381
+ ? { projectKey, docType: "OPENAPI", profile: "workspace-code", query: docQuery }
2382
+ : { projectKey, docType: "OPENAPI", profile: "workspace-code" };
2383
+ await appendDocs(sdsFilter);
2384
+ await appendDocs(openapiFilter);
2385
+ if (!docs.length) {
2386
+ const genericFilter = docQuery
2387
+ ? { projectKey, profile: "workspace-code", query: docQuery }
2388
+ : { projectKey, profile: "workspace-code" };
2389
+ await appendDocs(genericFilter);
2390
+ }
2290
2391
  if (!docs.length && docQuery) {
2291
- docs = await this.deps.docdex.search({ projectKey, profile: "workspace-code" });
2392
+ await appendDocs({ projectKey, profile: "workspace-code" });
2292
2393
  }
2293
2394
  const filteredDocs = docs.filter((doc) => !isDocContextExcluded(doc.path ?? doc.title ?? doc.id, false) &&
2294
2395
  (includeTestDocs || !isTestLikePath(doc.path ?? doc.title ?? doc.id)));
@@ -3389,12 +3490,14 @@ export class WorkOnTasksService {
3389
3490
  const commentBacklogMaxFails = resolveCommentBacklogMaxFails();
3390
3491
  const requestedMissingTestsPolicy = normalizeMissingTestsPolicy(request.missingTestsPolicy);
3391
3492
  const missingTestsPolicy = requestedMissingTestsPolicy ?? (request.allowMissingTests ? "skip_task" : DEFAULT_MISSING_TESTS_POLICY);
3493
+ const requestedExecutionContextPolicy = normalizeExecutionContextPolicy(request.executionContextPolicy);
3494
+ const executionContextPolicy = requestedExecutionContextPolicy ?? DEFAULT_EXECUTION_CONTEXT_POLICY;
3392
3495
  const baseCodaliEnvOverrides = codaliRequired ? buildCodaliEnvOverrides() : {};
3393
3496
  const configuredBaseBranch = this.workspace.config?.branch;
3394
3497
  const requestedBaseBranch = request.baseBranch;
3395
3498
  const resolvedBaseBranch = (requestedBaseBranch ?? configuredBaseBranch ?? DEFAULT_BASE_BRANCH).trim();
3396
3499
  const normalizedBaseBranch = resolvedBaseBranch === "dev" ? DEFAULT_BASE_BRANCH : resolvedBaseBranch;
3397
- const baseBranch = DEFAULT_BASE_BRANCH;
3500
+ const baseBranch = normalizedBaseBranch || DEFAULT_BASE_BRANCH;
3398
3501
  const configuredAutoMerge = this.workspace.config?.autoMerge;
3399
3502
  const configuredAutoPush = this.workspace.config?.autoPush;
3400
3503
  const autoMerge = request.autoMerge ?? configuredAutoMerge ?? true;
@@ -3405,7 +3508,12 @@ export class WorkOnTasksService {
3405
3508
  if (request.missingTestsPolicy && !requestedMissingTestsPolicy) {
3406
3509
  runnerWarnings.push(`Unknown missing-tests policy "${String(request.missingTestsPolicy)}"; using "${missingTestsPolicy}".`);
3407
3510
  }
3408
- const ignoreStatusFilter = Boolean(request.taskKeys?.length) || request.ignoreStatusFilter === true;
3511
+ if (request.executionContextPolicy && !requestedExecutionContextPolicy) {
3512
+ runnerWarnings.push(`Unknown execution-context policy "${String(request.executionContextPolicy)}"; using "${executionContextPolicy}".`);
3513
+ }
3514
+ const explicitTaskSelection = Boolean(request.taskKeys?.length);
3515
+ const ignoreDependencies = request.ignoreDependencies === true || explicitTaskSelection;
3516
+ const ignoreStatusFilter = explicitTaskSelection || request.ignoreStatusFilter === true;
3409
3517
  const { filtered: statusFilter, rejected } = ignoreStatusFilter
3410
3518
  ? { filtered: request.statusFilter ?? [], rejected: [] }
3411
3519
  : filterTaskStatuses(request.statusFilter, WORK_ALLOWED_STATUSES, WORK_ALLOWED_STATUSES);
@@ -3426,9 +3534,6 @@ export class WorkOnTasksService {
3426
3534
  if (codaliRequired && isPatchModeEnabled()) {
3427
3535
  runnerWarnings.push("work-on-tasks patch mode is ignored when codali is required.");
3428
3536
  }
3429
- if (normalizedBaseBranch && normalizedBaseBranch !== DEFAULT_BASE_BRANCH) {
3430
- baseBranchWarnings.push(`Base branch ${normalizedBaseBranch} ignored; work-on-tasks always uses ${DEFAULT_BASE_BRANCH}.`);
3431
- }
3432
3537
  const commandRun = await this.deps.jobService.startCommandRun(commandName, request.projectKey, {
3433
3538
  taskIds: request.taskKeys,
3434
3539
  });
@@ -3443,7 +3548,7 @@ export class WorkOnTasksService {
3443
3548
  ignoreStatusFilter,
3444
3549
  includeTypes,
3445
3550
  excludeTypes,
3446
- ignoreDependencies: true,
3551
+ ignoreDependencies,
3447
3552
  limit: request.limit,
3448
3553
  parallel: request.parallel,
3449
3554
  noCommit: request.noCommit ?? false,
@@ -3452,6 +3557,7 @@ export class WorkOnTasksService {
3452
3557
  agentStream,
3453
3558
  missingTestsPolicy,
3454
3559
  allowMissingTests: request.allowMissingTests ?? false,
3560
+ executionContextPolicy,
3455
3561
  },
3456
3562
  });
3457
3563
  const workspaceRoot = request.workspace.workspaceRoot;
@@ -3517,6 +3623,29 @@ export class WorkOnTasksService {
3517
3623
  return message === resolveAbortReason();
3518
3624
  };
3519
3625
  try {
3626
+ const warnings = [...baseBranchWarnings, ...statusWarnings, ...runnerWarnings];
3627
+ try {
3628
+ const guidance = await ensureProjectGuidance(this.workspace.workspaceRoot, {
3629
+ mcodaDir: this.workspace.mcodaDir,
3630
+ projectKey: request.projectKey,
3631
+ });
3632
+ if (guidance.status !== "existing") {
3633
+ warnings.push(`project_guidance_${guidance.status}: ${guidance.path}`);
3634
+ }
3635
+ for (const warning of guidance.warnings ?? []) {
3636
+ warnings.push(`project_guidance_warning:${warning}`);
3637
+ }
3638
+ }
3639
+ catch (error) {
3640
+ warnings.push(`project_guidance_bootstrap_failed: ${error instanceof Error ? error.message : String(error)}`);
3641
+ }
3642
+ const executionContext = await this.resolveExecutionPlanningContext(request.projectKey, warnings);
3643
+ this.enforceExecutionContextPolicy(executionContextPolicy, executionContext);
3644
+ await this.checkpoint(job.id, "execution_context_preflight", {
3645
+ policy: executionContextPolicy,
3646
+ source: executionContext?.source ?? null,
3647
+ kind: executionContext?.kind ?? null,
3648
+ });
3520
3649
  await this.checkoutBaseBranch(baseBranch, { allowDirty: true });
3521
3650
  selection = await this.selectionService.selectTasks({
3522
3651
  projectKey: request.projectKey,
@@ -3527,7 +3656,8 @@ export class WorkOnTasksService {
3527
3656
  ignoreStatusFilter,
3528
3657
  includeTypes,
3529
3658
  excludeTypes,
3530
- ignoreDependencies: true,
3659
+ ignoreDependencies,
3660
+ missingContextPolicy: request.missingContextPolicy ?? "block",
3531
3661
  limit: request.limit,
3532
3662
  parallel: request.parallel,
3533
3663
  });
@@ -3542,20 +3672,9 @@ export class WorkOnTasksService {
3542
3672
  totalItems: selection.ordered.length,
3543
3673
  processedItems: 0,
3544
3674
  });
3675
+ warnings.push(...selection.warnings);
3545
3676
  const results = [];
3546
3677
  const taskSummaries = new Map();
3547
- const warnings = [...baseBranchWarnings, ...statusWarnings, ...runnerWarnings, ...selection.warnings];
3548
- try {
3549
- const guidance = await ensureProjectGuidance(this.workspace.workspaceRoot, {
3550
- mcodaDir: this.workspace.mcodaDir,
3551
- });
3552
- if (guidance.status !== "existing") {
3553
- warnings.push(`project_guidance_${guidance.status}: ${guidance.path}`);
3554
- }
3555
- }
3556
- catch (error) {
3557
- warnings.push(`project_guidance_bootstrap_failed: ${error instanceof Error ? error.message : String(error)}`);
3558
- }
3559
3678
  if (missingTestsPolicy === "block_job") {
3560
3679
  const missingHarnessTasks = await this.findMissingTestHarnessTasks(selection.ordered);
3561
3680
  if (missingHarnessTasks.length > 0) {
@@ -4461,9 +4580,14 @@ export class WorkOnTasksService {
4461
4580
  continue taskLoop;
4462
4581
  }
4463
4582
  await endPhase("context", { docWarnings, docSummary: Boolean(docSummary) });
4464
- const projectGuidance = await loadProjectGuidance(this.workspace.workspaceRoot, this.workspace.mcodaDir);
4583
+ const projectGuidance = await loadProjectGuidance(this.workspace.workspaceRoot, this.workspace.mcodaDir, {
4584
+ projectKey: request.projectKey,
4585
+ });
4465
4586
  if (projectGuidance) {
4466
4587
  await this.logTask(taskRun.id, `Loaded project guidance from ${projectGuidance.source}`, "project_guidance");
4588
+ for (const warning of projectGuidance.warnings ?? []) {
4589
+ await this.logTask(taskRun.id, `Project guidance warning: ${warning}`, "project_guidance");
4590
+ }
4467
4591
  }
4468
4592
  await startPhase("prompt", { docSummary: Boolean(docSummary), agent: agent.id });
4469
4593
  commentContext = await this.loadCommentContext(task.task.id);
@@ -1 +1 @@
1
- {"version":3,"file":"OpenApiService.d.ts","sourceRoot":"","sources":["../../../src/services/openapi/OpenApiService.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"OpenApiService.d.ts","sourceRoot":"","sources":["../../../src/services/openapi/OpenApiService.ts"],"names":[],"mappings":"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"}
@@ -139,6 +139,7 @@ export const findAdminSurfaceMentions = (raw) => {
139
139
  };
140
140
  const HTTP_METHODS = ["get", "post", "put", "patch", "delete", "options", "head", "trace"];
141
141
  const OPERATION_ID_PATTERN = /^[A-Za-z0-9_.-]+$/;
142
+ const TASK_HINT_STAGE_VALUES = new Set(["foundation", "backend", "frontend", "other"]);
142
143
  const isPlainObject = (value) => Boolean(value && typeof value === "object" && !Array.isArray(value));
143
144
  const operationUsesJsonSchema = (operation) => {
144
145
  const contentBlocks = [];
@@ -230,6 +231,43 @@ export const validateOpenApiSchema = (doc) => {
230
231
  else {
231
232
  operationIds.set(operationId, `${method.toUpperCase()} ${pathKey}`);
232
233
  }
234
+ const taskHints = operation["x-mcoda-task-hints"];
235
+ if (taskHints !== undefined) {
236
+ if (!isPlainObject(taskHints)) {
237
+ errors.push(`Invalid x-mcoda-task-hints for ${method.toUpperCase()} ${pathKey}: must be an object.`);
238
+ }
239
+ else {
240
+ const stage = taskHints.stage;
241
+ if (stage !== undefined && (typeof stage !== "string" || !TASK_HINT_STAGE_VALUES.has(stage))) {
242
+ errors.push(`Invalid x-mcoda-task-hints.stage for ${method.toUpperCase()} ${pathKey}: expected one of foundation|backend|frontend|other.`);
243
+ }
244
+ const complexity = taskHints.complexity;
245
+ if (complexity !== undefined &&
246
+ (typeof complexity !== "number" || !Number.isFinite(complexity) || complexity < 0)) {
247
+ errors.push(`Invalid x-mcoda-task-hints.complexity for ${method.toUpperCase()} ${pathKey}: expected non-negative number.`);
248
+ }
249
+ const dependsOn = taskHints.depends_on_operations;
250
+ if (dependsOn !== undefined &&
251
+ (!Array.isArray(dependsOn) || dependsOn.some((entry) => typeof entry !== "string"))) {
252
+ errors.push(`Invalid x-mcoda-task-hints.depends_on_operations for ${method.toUpperCase()} ${pathKey}: expected string array.`);
253
+ }
254
+ const testRequirements = taskHints.test_requirements;
255
+ if (testRequirements !== undefined) {
256
+ if (!isPlainObject(testRequirements)) {
257
+ errors.push(`Invalid x-mcoda-task-hints.test_requirements for ${method.toUpperCase()} ${pathKey}: expected object.`);
258
+ }
259
+ else {
260
+ for (const key of ["unit", "component", "integration", "api"]) {
261
+ const value = testRequirements[key];
262
+ if (value !== undefined &&
263
+ (!Array.isArray(value) || value.some((entry) => typeof entry !== "string"))) {
264
+ errors.push(`Invalid x-mcoda-task-hints.test_requirements.${key} for ${method.toUpperCase()} ${pathKey}: expected string array.`);
265
+ }
266
+ }
267
+ }
268
+ }
269
+ }
270
+ }
233
271
  }
234
272
  }
235
273
  }
@@ -400,7 +438,7 @@ class OpenapiContextAssembler {
400
438
  sdsDocs = [local];
401
439
  }
402
440
  else {
403
- warnings.push("No SDS found in docdex or local workspace.");
441
+ throw new Error("openapi-from-docs requires an SDS document. Generate SDS first (mcoda docs sds generate) or add docs/sds/sds.md.");
404
442
  }
405
443
  }
406
444
  else {
@@ -594,8 +632,8 @@ export class OpenApiService {
594
632
  : "";
595
633
  return [
596
634
  "You are generating an OpenAPI 3.1 YAML for THIS workspace/project using only the provided PDR/SDS/RFP context.",
597
- "Derive resources, schemas, and HTTP endpoints directly from the product requirements (e.g., todos CRUD, filters, search, bulk actions).",
598
- "If the documents describe a frontend-only/localStorage app, design a minimal REST API that could back those features (e.g., /todos, /todos/{id}, bulk operations, search/filter params) instead of returning an empty spec.",
635
+ "Derive resources, schemas, and HTTP endpoints directly from SDS-grounded product requirements only.",
636
+ "Do not invent endpoints, workflows, or schemas that are not traceable to SDS/PDR/RFP context.",
599
637
  "Prefer concise tags derived from domain resources (e.g., Todos). Avoid generic mcoda/system endpoints unless explicitly described in the context.",
600
638
  `Use OpenAPI version ${OPENAPI_VERSION}, set info.title to the project name from context (fallback \"mcoda API\"), and info.version ${cliVersion}.`,
601
639
  adminNote,
@@ -605,8 +643,9 @@ export class OpenApiService {
605
643
  "- Derive endpoints, schemas, and tags from the provided PDR/SDS/RFP context only.",
606
644
  "- Do NOT emit generic mcoda CLI/system endpoints unless explicitly described.",
607
645
  "- Prefer concise schemas and operations that map to described APIs; omit unused boilerplate.",
646
+ "- For each operation, include x-mcoda-task-hints with fields: service (string), capability (string), stage (foundation|backend|frontend|other), complexity (number), depends_on_operations (string[]), test_requirements ({ unit: string[], component: string[], integration: string[], api: string[] }).",
608
647
  "Context:",
609
- contextBlocks || "No context available; if none, produce a minimal empty spec with paths: {}.",
648
+ contextBlocks || "SDS context is required and should always be present.",
610
649
  ].join("\n\n");
611
650
  }
612
651
  async ensureOpenapiDir() {
@@ -58,10 +58,19 @@ export declare class CreateTasksService {
58
58
  });
59
59
  static create(workspace: WorkspaceResolution): Promise<CreateTasksService>;
60
60
  close(): Promise<void>;
61
+ private storyScopeKey;
62
+ private taskScopeKey;
63
+ private scopeStory;
64
+ private scopeTask;
61
65
  private seedPriorities;
62
66
  private resolveAgent;
63
67
  private ensureRatingService;
64
68
  private prepareDocs;
69
+ private normalizeDocInputForSet;
70
+ private docIdentity;
71
+ private mergeDocs;
72
+ private sortDocsForPlanning;
73
+ private collectDocsFromInputs;
65
74
  private resolveDefaultDocInputs;
66
75
  private walkDocCandidates;
67
76
  private scoreDocCandidate;
@@ -74,18 +83,24 @@ export declare class CreateTasksService {
74
83
  private extractServiceMentionsFromText;
75
84
  private resolveServiceMentionFromPhrase;
76
85
  private collectDependencyStatements;
86
+ private extractStartupWaveHints;
77
87
  private sortServicesByDependency;
78
88
  private buildServiceDependencyGraph;
89
+ private buildProjectConstructionMethod;
79
90
  private orderStoryTasksByDependencies;
80
91
  private applyServiceDependencySequencing;
81
92
  private shouldInjectStructureBootstrap;
82
93
  private injectStructureBootstrapPlan;
83
94
  private enforceStoryScopedDependencies;
95
+ private validatePlanLocalIdentifiers;
84
96
  private buildQaPreflight;
85
97
  private buildQaOverrides;
98
+ private isOpenApiDoc;
99
+ private buildOpenApiHintSummary;
86
100
  private buildDocContext;
87
101
  private buildPrompt;
88
102
  private fallbackPlan;
103
+ private materializePlanFromSeed;
89
104
  private invokeAgentWithRetry;
90
105
  private parseEpics;
91
106
  private generateStoriesForEpic;
@@ -1 +1 @@
1
- {"version":3,"file":"CreateTasksService.d.ts","sourceRoot":"","sources":["../../../src/services/planning/CreateTasksService.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"CreateTasksService.d.ts","sourceRoot":"","sources":["../../../src/services/planning/CreateTasksService.ts"],"names":[],"mappings":"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"}