@mcoda/core 0.1.33 → 0.1.35

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 (26) hide show
  1. package/dist/api/AgentsApi.d.ts +4 -1
  2. package/dist/api/AgentsApi.d.ts.map +1 -1
  3. package/dist/api/AgentsApi.js +4 -1
  4. package/dist/services/docs/DocsService.d.ts +37 -0
  5. package/dist/services/docs/DocsService.d.ts.map +1 -1
  6. package/dist/services/docs/DocsService.js +537 -2
  7. package/dist/services/docs/review/gates/OpenQuestionsGate.d.ts.map +1 -1
  8. package/dist/services/docs/review/gates/OpenQuestionsGate.js +13 -2
  9. package/dist/services/docs/review/gates/SdsNoUnresolvedItemsGate.d.ts.map +1 -1
  10. package/dist/services/docs/review/gates/SdsNoUnresolvedItemsGate.js +12 -1
  11. package/dist/services/planning/CreateTasksService.d.ts +30 -0
  12. package/dist/services/planning/CreateTasksService.d.ts.map +1 -1
  13. package/dist/services/planning/CreateTasksService.js +1269 -178
  14. package/dist/services/planning/SdsCoverageModel.d.ts +27 -0
  15. package/dist/services/planning/SdsCoverageModel.d.ts.map +1 -0
  16. package/dist/services/planning/SdsCoverageModel.js +138 -0
  17. package/dist/services/planning/SdsPreflightService.d.ts +2 -0
  18. package/dist/services/planning/SdsPreflightService.d.ts.map +1 -1
  19. package/dist/services/planning/SdsPreflightService.js +125 -31
  20. package/dist/services/planning/SdsStructureSignals.d.ts +24 -0
  21. package/dist/services/planning/SdsStructureSignals.d.ts.map +1 -0
  22. package/dist/services/planning/SdsStructureSignals.js +402 -0
  23. package/dist/services/planning/TaskSufficiencyService.d.ts +1 -0
  24. package/dist/services/planning/TaskSufficiencyService.d.ts.map +1 -1
  25. package/dist/services/planning/TaskSufficiencyService.js +218 -285
  26. package/package.json +6 -6
@@ -0,0 +1,27 @@
1
+ export interface SdsCoverageSignalSet {
2
+ rawSectionHeadings: string[];
3
+ rawFolderEntries: string[];
4
+ sectionHeadings: string[];
5
+ folderEntries: string[];
6
+ skippedHeadingSignals: number;
7
+ skippedFolderSignals: number;
8
+ }
9
+ export interface SdsCoverageSummary {
10
+ coverageRatio: number;
11
+ totalSignals: number;
12
+ missingSectionHeadings: string[];
13
+ missingFolderEntries: string[];
14
+ }
15
+ export declare const normalizeCoverageText: (value: string) => string;
16
+ export declare const normalizeCoverageAnchor: (kind: "section" | "folder", value: string) => string;
17
+ export declare const collectSdsCoverageSignalsFromDocs: (docs: Array<{
18
+ content?: string | null;
19
+ }>, options: {
20
+ headingLimit: number;
21
+ folderLimit: number;
22
+ }) => SdsCoverageSignalSet;
23
+ export declare const evaluateSdsCoverage: (corpus: string, signals: {
24
+ sectionHeadings: string[];
25
+ folderEntries: string[];
26
+ }, existingAnchors?: Set<string>) => SdsCoverageSummary;
27
+ //# sourceMappingURL=SdsCoverageModel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SdsCoverageModel.d.ts","sourceRoot":"","sources":["../../../src/services/planning/SdsCoverageModel.ts"],"names":[],"mappings":"AA6BA,MAAM,WAAW,oBAAoB;IACnC,kBAAkB,EAAE,MAAM,EAAE,CAAC;IAC7B,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,qBAAqB,EAAE,MAAM,CAAC;IAC9B,oBAAoB,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,WAAW,kBAAkB;IACjC,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,sBAAsB,EAAE,MAAM,EAAE,CAAC;IACjC,oBAAoB,EAAE,MAAM,EAAE,CAAC;CAChC;AAED,eAAO,MAAM,qBAAqB,GAAI,OAAO,MAAM,KAAG,MAM3C,CAAC;AAEZ,eAAO,MAAM,uBAAuB,GAAI,MAAM,SAAS,GAAG,QAAQ,EAAE,OAAO,MAAM,KAAG,MACb,CAAC;AA6ExE,eAAO,MAAM,iCAAiC,GAC5C,MAAM,KAAK,CAAC;IAAE,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC,EACxC,SAAS;IAAE,YAAY,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,KACrD,oBAmBF,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAC9B,QAAQ,MAAM,EACd,SAAS;IAAE,eAAe,EAAE,MAAM,EAAE,CAAC;IAAC,aAAa,EAAE,MAAM,EAAE,CAAA;CAAE,EAC/D,kBAAiB,GAAG,CAAC,MAAM,CAAa,KACvC,kBAoBF,CAAC"}
@@ -0,0 +1,138 @@
1
+ import { collectSdsImplementationSignals, normalizeFolderEntry, normalizeHeadingCandidate, } from "./SdsStructureSignals.js";
2
+ const coverageStopTokens = new Set([
3
+ "about",
4
+ "across",
5
+ "after",
6
+ "before",
7
+ "between",
8
+ "from",
9
+ "into",
10
+ "over",
11
+ "under",
12
+ "using",
13
+ "with",
14
+ "without",
15
+ "onto",
16
+ "the",
17
+ "and",
18
+ "for",
19
+ "of",
20
+ "to",
21
+ ]);
22
+ const unique = (items) => Array.from(new Set(items.filter(Boolean)));
23
+ export const normalizeCoverageText = (value) => value
24
+ .toLowerCase()
25
+ .replace(/[`*_]/g, " ")
26
+ .replace(/[^a-z0-9/\s.-]+/g, " ")
27
+ .replace(/\s+/g, " ")
28
+ .trim();
29
+ export const normalizeCoverageAnchor = (kind, value) => `${kind}:${normalizeCoverageText(value).replace(/\s+/g, " ").trim()}`;
30
+ const tokenizeCoverageSignal = (value) => unique(value
31
+ .split(/\s+/)
32
+ .map((token) => token.replace(/[^a-z0-9._-]+/g, ""))
33
+ .filter((token) => token.length >= 3 && !coverageStopTokens.has(token)));
34
+ const buildBigrams = (tokens) => {
35
+ const bigrams = [];
36
+ for (let index = 0; index < tokens.length - 1; index += 1) {
37
+ const left = tokens[index];
38
+ const right = tokens[index + 1];
39
+ if (!left || !right)
40
+ continue;
41
+ bigrams.push(`${left} ${right}`);
42
+ }
43
+ return unique(bigrams);
44
+ };
45
+ const headingCovered = (corpus, heading) => {
46
+ const normalized = normalizeCoverageText(normalizeHeadingCandidate(heading));
47
+ if (!normalized)
48
+ return true;
49
+ if (corpus.includes(normalized))
50
+ return true;
51
+ const tokens = tokenizeCoverageSignal(normalized).slice(0, 10);
52
+ if (tokens.length === 0)
53
+ return true;
54
+ const hitCount = tokens.filter((token) => corpus.includes(token)).length;
55
+ const requiredHits = tokens.length <= 2
56
+ ? tokens.length
57
+ : tokens.length <= 4
58
+ ? 2
59
+ : Math.min(4, Math.ceil(tokens.length * 0.6));
60
+ if (hitCount < requiredHits)
61
+ return false;
62
+ if (tokens.length >= 3) {
63
+ const longestToken = tokens.reduce((longest, token) => (token.length > longest.length ? token : longest), "");
64
+ if (longestToken.length >= 6 && !corpus.includes(longestToken))
65
+ return false;
66
+ }
67
+ const bigrams = buildBigrams(tokens);
68
+ if (tokens.length >= 3 && bigrams.length > 0 && !bigrams.some((bigram) => corpus.includes(bigram))) {
69
+ return false;
70
+ }
71
+ return true;
72
+ };
73
+ const folderEntryCovered = (corpus, entry) => {
74
+ const normalizedEntry = normalizeFolderEntry(entry)?.toLowerCase().replace(/\/+/g, "/");
75
+ if (!normalizedEntry)
76
+ return true;
77
+ const corpusTight = corpus.replace(/\s+/g, "");
78
+ if (corpusTight.includes(normalizedEntry.replace(/\s+/g, "")))
79
+ return true;
80
+ const segments = normalizedEntry
81
+ .split("/")
82
+ .map((segment) => segment.trim().replace(/[^a-z0-9._-]+/g, ""))
83
+ .filter(Boolean);
84
+ if (segments.length === 0)
85
+ return true;
86
+ const tailSegments = unique(segments.slice(Math.max(0, segments.length - 3)));
87
+ const hitCount = tailSegments.filter((segment) => corpus.includes(segment)).length;
88
+ const requiredHits = tailSegments.length <= 1 ? 1 : Math.min(2, tailSegments.length);
89
+ if (hitCount < requiredHits)
90
+ return false;
91
+ if (tailSegments.length >= 2) {
92
+ const hasStrongTokenMatch = tailSegments.some((segment) => segment.length >= 5 && corpus.includes(segment));
93
+ if (!hasStrongTokenMatch)
94
+ return false;
95
+ }
96
+ return true;
97
+ };
98
+ export const collectSdsCoverageSignalsFromDocs = (docs, options) => {
99
+ const docSignals = docs.map((doc) => collectSdsImplementationSignals(doc.content ?? "", {
100
+ headingLimit: options.headingLimit,
101
+ folderLimit: options.folderLimit,
102
+ }));
103
+ const rawSectionHeadings = unique(docSignals.flatMap((signals) => signals.rawSectionHeadings));
104
+ const rawFolderEntries = unique(docSignals.flatMap((signals) => signals.rawFolderEntries));
105
+ const sectionHeadings = unique(docSignals.flatMap((signals) => signals.sectionHeadings)).slice(0, options.headingLimit);
106
+ const folderEntries = unique(docSignals.flatMap((signals) => signals.folderEntries)).slice(0, options.folderLimit);
107
+ return {
108
+ rawSectionHeadings,
109
+ rawFolderEntries,
110
+ sectionHeadings,
111
+ folderEntries,
112
+ skippedHeadingSignals: Math.max(0, rawSectionHeadings.length - sectionHeadings.length),
113
+ skippedFolderSignals: Math.max(0, rawFolderEntries.length - folderEntries.length),
114
+ };
115
+ };
116
+ export const evaluateSdsCoverage = (corpus, signals, existingAnchors = new Set()) => {
117
+ const missingSectionHeadings = signals.sectionHeadings.filter((heading) => {
118
+ const anchor = normalizeCoverageAnchor("section", heading);
119
+ if (existingAnchors.has(anchor))
120
+ return false;
121
+ return !headingCovered(corpus, heading);
122
+ });
123
+ const missingFolderEntries = signals.folderEntries.filter((entry) => {
124
+ const anchor = normalizeCoverageAnchor("folder", entry);
125
+ if (existingAnchors.has(anchor))
126
+ return false;
127
+ return !folderEntryCovered(corpus, entry);
128
+ });
129
+ const totalSignals = signals.sectionHeadings.length + signals.folderEntries.length;
130
+ const coveredSignals = totalSignals - missingSectionHeadings.length - missingFolderEntries.length;
131
+ const coverageRatio = totalSignals === 0 ? 1 : coveredSignals / totalSignals;
132
+ return {
133
+ coverageRatio: Number(coverageRatio.toFixed(4)),
134
+ totalSignals,
135
+ missingSectionHeadings,
136
+ missingFolderEntries,
137
+ };
138
+ };
@@ -59,7 +59,9 @@ export declare class SdsPreflightService {
59
59
  private walkCandidates;
60
60
  private collectPathCandidates;
61
61
  private discoverSdsPaths;
62
+ private countSdsSectionSignals;
62
63
  private isLikelySdsPath;
64
+ private selectLikelySdsPaths;
63
65
  private resolveSdsPaths;
64
66
  private buildArtifacts;
65
67
  private getGateRunners;
@@ -1 +1 @@
1
- {"version":3,"file":"SdsPreflightService.d.ts","sourceRoot":"","sources":["../../../src/services/planning/SdsPreflightService.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;AAM1E,OAAO,EAIL,KAAK,cAAc,EACpB,MAAM,+BAA+B,CAAC;AA8IvC,MAAM,WAAW,0BAA0B;IACzC,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB;AAED,MAAM,WAAW,wBAAwB;IACvC,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,cAAc,CAAC;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,aAAa,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;IACxC,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,eAAe,EAAE,MAAM,CAAC;IACxB,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,aAAa,EAAE,MAAM,CAAC;IACtB,qBAAqB,EAAE,MAAM,CAAC;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,YAAY,EAAE,OAAO,CAAC;IACtB,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,wBAAwB,EAAE,CAAC;IACnC,SAAS,EAAE,0BAA0B,EAAE,CAAC;IACxC,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,mBAAmB,CAAC;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAsB;gBAEpC,SAAS,EAAE,mBAAmB;WAI7B,MAAM,CAAC,SAAS,EAAE,mBAAmB,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAI3E,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;YAId,cAAc;YAwBd,qBAAqB;YAwBrB,gBAAgB;YAwBhB,eAAe;YAWf,eAAe;IAe7B,OAAO,CAAC,cAAc;IAWtB,OAAO,CAAC,cAAc;IAatB,OAAO,CAAC,YAAY;IAkBpB,OAAO,CAAC,oBAAoB;IAI5B,OAAO,CAAC,yBAAyB;YA2CnB,oBAAoB;IAoBlC,OAAO,CAAC,cAAc;IAQtB,OAAO,CAAC,iBAAiB;IAmHzB,OAAO,CAAC,wBAAwB;IA6BhC,OAAO,CAAC,wBAAwB;IAoBhC,OAAO,CAAC,6BAA6B;IAgCrC,OAAO,CAAC,wBAAwB;IA+BhC,OAAO,CAAC,qBAAqB;IAc7B,OAAO,CAAC,sBAAsB;IAQ9B,OAAO,CAAC,mBAAmB;IAiB3B,OAAO,CAAC,sBAAsB;IA0C9B,OAAO,CAAC,YAAY;IAqBpB,OAAO,CAAC,gBAAgB;IAkDxB,OAAO,CAAC,iBAAiB;IAqBzB,OAAO,CAAC,aAAa;IAyCrB,OAAO,CAAC,iBAAiB;IAmCzB,OAAO,CAAC,eAAe;YAeT,kBAAkB;IA6BhC,OAAO,CAAC,gBAAgB;IAOxB,OAAO,CAAC,mBAAmB;IAK3B,OAAO,CAAC,qBAAqB;IAQ7B,OAAO,CAAC,4BAA4B;IA0BpC,OAAO,CAAC,qBAAqB;IAc7B,OAAO,CAAC,oBAAoB;IA2D5B,OAAO,CAAC,qBAAqB;YAwBf,+BAA+B;YAwC/B,uBAAuB;IAqC/B,YAAY,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,kBAAkB,CAAC;CAiG9E"}
1
+ {"version":3,"file":"SdsPreflightService.d.ts","sourceRoot":"","sources":["../../../src/services/planning/SdsPreflightService.ts"],"names":[],"mappings":"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"}
@@ -32,8 +32,24 @@ const ignoredDirs = new Set([
32
32
  "tmp",
33
33
  "temp",
34
34
  ]);
35
- const sdsFilenamePattern = /(sds|software[-_ ]design|system[-_ ]design|design[-_ ]spec|architecture)/i;
36
- const sdsContentPattern = /(software design specification|system design specification|^#\s*sds\b)/im;
35
+ const strongSdsFilenamePattern = /(sds|software[-_ ]design|system[-_ ]design|design[-_ ]spec)/i;
36
+ const strongSdsDirectoryPattern = /(?:^|[/\\])sds(?:[/\\]|$)/i;
37
+ const weakSdsFilenamePattern = /architecture/i;
38
+ const sdsTitlePattern = /^#\s*(?:software design specification|system design specification|sds)\b/im;
39
+ const nonSdsTitlePattern = /^#\s*(?:product design review|pdr|request for proposal|rfp)\b/im;
40
+ const sdsSectionPatterns = [
41
+ /^#{1,6}\s+open questions\b/im,
42
+ /^#{1,6}\s+folder tree\b/im,
43
+ /^#{1,6}\s+technology stack\b/im,
44
+ /^#{1,6}\s+policy(?: and cache consent)?\b/im,
45
+ /^#{1,6}\s+telemetry\b/im,
46
+ /^#{1,6}\s+(?:metering and usage|metering|usage)\b/im,
47
+ /^#{1,6}\s+(?:operations and deployment|operations|deployment)\b/im,
48
+ /^#{1,6}\s+observability\b/im,
49
+ /^#{1,6}\s+testing gates\b/im,
50
+ /^#{1,6}\s+(?:failure recovery and rollback|failure modes(?:, recovery, and rollback)?)\b/im,
51
+ /^#{1,6}\s+external integrations and adapter contracts\b/im,
52
+ ];
37
53
  const markdownPattern = /\.(md|markdown|txt|rst)$/i;
38
54
  const unresolvedTokenPattern = /\b(TBD|TBC|TODO|FIXME|to be determined|to be decided|unknown|unresolved)\b/gi;
39
55
  const sdsHeadingLinePattern = /^#{1,6}\s+(.+)$/;
@@ -78,6 +94,14 @@ const environmentMatchers = [
78
94
  { label: "staging", pattern: /\bstaging\b|\bpre-?prod\b/i },
79
95
  { label: "production", pattern: /\bprod(uction)?\b/i },
80
96
  ];
97
+ const documentationSegmentPattern = /^(docs?|design|specs?|runbooks?|adr|architecture)$/i;
98
+ const implementationSegmentPattern = /^(src|app|apps|service|services|worker|workers|module|modules|package|packages|lib|libs|engine|engines|console|consoles|runtime|runtimes)$/i;
99
+ const interfaceSegmentPattern = /^(api|apis|openapi|swagger|graphql|proto|schema|schemas|contract|contracts|interface|interfaces)$/i;
100
+ const storageSegmentPattern = /^(db|data|storage|schema|schemas|migration|migrations|sql|seed|seeds)$/i;
101
+ const automationSegmentPattern = /^(script|scripts|tool|tools|bin|cmd|cli|automation)$/i;
102
+ const operationsSegmentPattern = /^(ops|deploy|deployment|deployments|infra|infrastructure|terraform|helm|k8s|kubernetes|systemd)$/i;
103
+ const validationSegmentPattern = /^(test|tests|testing|spec|specs|e2e|qa|fixtures)$/i;
104
+ const staticAssetSegmentPattern = /^(public|static|assets)$/i;
81
105
  const moduleNoiseTokens = new Set([
82
106
  "and",
83
107
  "for",
@@ -101,6 +125,47 @@ const moduleNoiseTokens = new Set([
101
125
  ]);
102
126
  const execFileAsync = promisify(execFile);
103
127
  const uniqueStrings = (values) => Array.from(new Set(values.filter(Boolean)));
128
+ const stripManagedPreflightBlocks = (content) => {
129
+ let updated = content;
130
+ while (true) {
131
+ const startIndex = updated.indexOf(MANAGED_SDS_BLOCK_START);
132
+ if (startIndex < 0)
133
+ break;
134
+ const endIndex = updated.indexOf(MANAGED_SDS_BLOCK_END, startIndex);
135
+ if (endIndex < 0)
136
+ break;
137
+ updated = `${updated.slice(0, startIndex)}\n${updated.slice(endIndex + MANAGED_SDS_BLOCK_END.length)}`;
138
+ }
139
+ return updated;
140
+ };
141
+ const describeFolderEntry = (entry) => {
142
+ if (/\s+#/.test(entry))
143
+ return "";
144
+ const segments = entry
145
+ .replace(/^\.?\//, "")
146
+ .split("/")
147
+ .map((segment) => segment.trim().toLowerCase())
148
+ .filter(Boolean);
149
+ if (segments.length === 0)
150
+ return "implementation surface";
151
+ if (segments.some((segment) => documentationSegmentPattern.test(segment)))
152
+ return "documentation and planning inputs";
153
+ if (segments.some((segment) => validationSegmentPattern.test(segment)))
154
+ return "automated validation surfaces";
155
+ if (segments.some((segment) => automationSegmentPattern.test(segment)))
156
+ return "automation and command entrypoints";
157
+ if (segments.some((segment) => operationsSegmentPattern.test(segment)))
158
+ return "deployment and operations assets";
159
+ if (segments.some((segment) => storageSegmentPattern.test(segment)))
160
+ return "storage and schema assets";
161
+ if (segments.some((segment) => interfaceSegmentPattern.test(segment)))
162
+ return "interface definitions and compatibility surfaces";
163
+ if (segments.some((segment) => staticAssetSegmentPattern.test(segment)))
164
+ return "runtime assets";
165
+ if (segments.some((segment) => implementationSegmentPattern.test(segment)))
166
+ return "implementation surfaces";
167
+ return segments.length >= 2 ? "implementation surface" : "top-level workspace surface";
168
+ };
104
169
  const normalizeQuestion = (value) => value
105
170
  .toLowerCase()
106
171
  .replace(/[^a-z0-9]+/g, " ")
@@ -213,25 +278,34 @@ export class SdsPreflightService {
213
278
  });
214
279
  return uniqueStrings(discovered).slice(0, SDS_SCAN_MAX_FILES);
215
280
  }
281
+ countSdsSectionSignals(sample) {
282
+ const effectiveSample = stripManagedPreflightBlocks(sample);
283
+ return sdsSectionPatterns.reduce((count, pattern) => count + (pattern.test(effectiveSample) ? 1 : 0), 0);
284
+ }
216
285
  async isLikelySdsPath(filePath) {
217
286
  const baseName = path.basename(filePath);
218
- if (sdsFilenamePattern.test(baseName))
219
- return true;
287
+ const normalizedPath = filePath.replace(/\\/g, "/");
220
288
  try {
221
- const sample = (await fs.readFile(filePath, "utf8")).slice(0, 35000);
222
- return sdsContentPattern.test(sample);
289
+ const rawSample = (await fs.readFile(filePath, "utf8")).slice(0, 35000);
290
+ const sample = stripManagedPreflightBlocks(rawSample);
291
+ if (nonSdsTitlePattern.test(sample))
292
+ return false;
293
+ if (sdsTitlePattern.test(sample))
294
+ return true;
295
+ if (strongSdsFilenamePattern.test(baseName) || strongSdsDirectoryPattern.test(normalizedPath)) {
296
+ return true;
297
+ }
298
+ if (!weakSdsFilenamePattern.test(baseName))
299
+ return false;
300
+ return this.countSdsSectionSignals(sample) >= 3;
223
301
  }
224
302
  catch {
225
303
  return false;
226
304
  }
227
305
  }
228
- async resolveSdsPaths(options) {
229
- const explicit = await this.collectPathCandidates(options.sdsPaths);
230
- const fromInputs = await this.collectPathCandidates(options.inputPaths);
231
- const discovered = await this.discoverSdsPaths();
232
- const candidatePaths = uniqueStrings([...explicit, ...fromInputs, ...discovered]).slice(0, SDS_SCAN_MAX_FILES);
306
+ async selectLikelySdsPaths(candidatePaths) {
233
307
  const selected = [];
234
- for (const candidate of candidatePaths) {
308
+ for (const candidate of uniqueStrings(candidatePaths).slice(0, SDS_SCAN_MAX_FILES)) {
235
309
  if (await this.isLikelySdsPath(candidate)) {
236
310
  selected.push(path.resolve(candidate));
237
311
  }
@@ -240,6 +314,19 @@ export class SdsPreflightService {
240
314
  }
241
315
  return uniqueStrings(selected);
242
316
  }
317
+ async resolveSdsPaths(options) {
318
+ const explicit = await this.collectPathCandidates(options.sdsPaths);
319
+ if (explicit.length > 0) {
320
+ return this.selectLikelySdsPaths(explicit);
321
+ }
322
+ const fromInputs = await this.collectPathCandidates(options.inputPaths);
323
+ const selectedFromInputs = await this.selectLikelySdsPaths(fromInputs);
324
+ if (selectedFromInputs.length > 0) {
325
+ return selectedFromInputs;
326
+ }
327
+ const discovered = await this.discoverSdsPaths();
328
+ return this.selectLikelySdsPaths(discovered);
329
+ }
243
330
  buildArtifacts(sdsPath) {
244
331
  const artifacts = createEmptyArtifacts();
245
332
  artifacts.sds = {
@@ -286,7 +373,7 @@ export class SdsPreflightService {
286
373
  return path.isAbsolute(filePath) ? path.resolve(filePath) : path.resolve(this.workspace.workspaceRoot, filePath);
287
374
  }
288
375
  collectSignalsFromContent(content) {
289
- const lines = content.split(/\r?\n/);
376
+ const lines = stripManagedPreflightBlocks(content).split(/\r?\n/);
290
377
  const headings = [];
291
378
  const folderEntries = [];
292
379
  for (const line of lines) {
@@ -445,12 +532,17 @@ export class SdsPreflightService {
445
532
  }
446
533
  managedFolderTreeSection(signals) {
447
534
  const entries = signals?.folderEntries?.slice(0, 10) ?? [];
535
+ const annotateEntry = (entry, isLast) => {
536
+ const hint = describeFolderEntry(entry);
537
+ const prefix = isLast ? "└──" : "├──";
538
+ return hint ? `${prefix} ${entry} # ${hint}` : `${prefix} ${entry}`;
539
+ };
448
540
  if (entries.length > 0) {
449
541
  return [
450
542
  "## Folder Tree",
451
543
  "```text",
452
544
  ".",
453
- ...entries.map((entry, index) => `${index === entries.length - 1 ? "└──" : "├──"} ${entry}`),
545
+ ...entries.map((entry, index) => annotateEntry(entry, index === entries.length - 1)),
454
546
  "```",
455
547
  "",
456
548
  ];
@@ -459,14 +551,12 @@ export class SdsPreflightService {
459
551
  "## Folder Tree",
460
552
  "```text",
461
553
  ".",
462
- "├── docs/",
463
- "├── apps/web/",
464
- "├── services/api/",
465
- "├── services/worker/",
466
- "├── packages/shared/",
467
- "├── db/migrations/",
468
- "├── tests/",
469
- "└── scripts/",
554
+ "├── docs/architecture/ # documentation and planning inputs",
555
+ "├── modules/core/ # implementation surfaces",
556
+ "├── interfaces/public/ # interface definitions and compatibility surfaces",
557
+ "├── data/migrations/ # storage and schema assets",
558
+ "├── tests/integration/ # automated validation surfaces",
559
+ "└── tools/release/ # automation and command entrypoints",
470
560
  "```",
471
561
  "",
472
562
  ];
@@ -878,24 +968,24 @@ export class SdsPreflightService {
878
968
  const scopedIssues = issues.filter((issue) => this.issueMatchesPath(issue, sdsPath));
879
969
  const lines = [
880
970
  MANAGED_SDS_BLOCK_START,
881
- "## Open Questions (Resolved)",
971
+ "## Planning Decisions (mcoda preflight)",
882
972
  "",
883
973
  ];
884
974
  if (scopedQuestions.length === 0) {
885
- lines.push("- Resolved: No unresolved questions remain for this SDS file in this preflight run.");
975
+ lines.push("- Decision coverage baseline recorded for this SDS file in this preflight run.");
886
976
  lines.push("");
887
977
  }
888
978
  else {
889
979
  scopedQuestions.forEach((question, index) => {
890
980
  const summary = this.normalizeResolvedText(question.answer);
891
- const prefix = summary || "Explicit decision recorded in managed preflight output.";
892
- lines.push(`- Resolved: Decision ${index + 1} for "${question.question}" => ${prefix}`);
981
+ const prefix = summary || "Explicit implementation decision recorded in managed preflight output.";
982
+ lines.push(`- Decision ${index + 1}: ${prefix}`);
893
983
  });
894
984
  lines.push("");
895
985
  }
896
- lines.push("## Resolved Decisions (mcoda preflight)");
897
- lines.push("- Decision baseline: unresolved items are converted into explicit implementation decisions.");
898
- lines.push("- Planning rule: each resolved decision must map to implementation and QA verification work.");
986
+ lines.push("## Decision Summary (mcoda preflight)");
987
+ lines.push("- Decision baseline: preflight converts planning ambiguities into explicit implementation guidance.");
988
+ lines.push("- Planning rule: each captured decision maps to implementation and QA verification work.");
899
989
  if (signals?.moduleDomains && signals.moduleDomains.length > 0) {
900
990
  lines.push(`- Module scope detected for this SDS file: ${signals.moduleDomains.slice(0, 6).join(", ")}.`);
901
991
  }
@@ -908,12 +998,13 @@ export class SdsPreflightService {
908
998
  lines.push("## Gap Remediation Summary (mcoda preflight)");
909
999
  lines.push("");
910
1000
  if (scopedIssues.length === 0) {
911
- lines.push("- No unresolved SDS quality gaps remained for this SDS file in this preflight run.");
1001
+ lines.push("- No remaining SDS quality gaps were detected for this SDS file in this preflight run.");
912
1002
  lines.push("");
913
1003
  }
914
1004
  else {
915
1005
  scopedIssues.forEach((issue, index) => {
916
- lines.push(`### Gap ${index + 1}: ${issue.message}`);
1006
+ const gapSummary = this.normalizeResolvedText(issue.message) || issue.message;
1007
+ lines.push(`### Gap ${index + 1}: ${gapSummary}`);
917
1008
  lines.push(`- Gate: ${issue.gateId}`);
918
1009
  lines.push(`- Source: ${formatIssueLocation(issue)}`);
919
1010
  lines.push("- Remediation:");
@@ -1022,6 +1113,9 @@ export class SdsPreflightService {
1022
1113
  let issues = this.dedupeIssues(outcome.issues);
1023
1114
  let questions = this.extractQuestionAnswers(issues, signalsByPath);
1024
1115
  const applyToSds = options.applyToSds === true;
1116
+ if (options.commitAppliedChanges && !applyToSds) {
1117
+ warnings.push("SDS preflight commit was requested without applyToSds; skipping commit because source SDS writeback is disabled.");
1118
+ }
1025
1119
  let appliedSdsPaths = [];
1026
1120
  if (applyToSds) {
1027
1121
  const applyResult = await this.applyPreflightRemediationsToSds({
@@ -0,0 +1,24 @@
1
+ export declare const isStructuredFilePath: (value: string) => boolean;
2
+ export declare const stripManagedSdsPreflightBlock: (value: string | undefined) => string | undefined;
3
+ export declare const normalizeHeadingCandidate: (value: string) => string;
4
+ export declare const headingLooksImplementationRelevant: (heading: string) => boolean;
5
+ export declare const pruneParentImplementationHeadings: (headings: string[]) => string[];
6
+ export declare const normalizeStructuredPathToken: (value: string) => string | undefined;
7
+ export declare const normalizeFolderEntry: (entry: string) => string | undefined;
8
+ export declare const extractStructuredPaths: (content: string, limit: number) => string[];
9
+ export declare const extractMarkdownHeadings: (content: string, limit: number) => string[];
10
+ export declare const folderEntryLooksRepoRelevant: (entry: string) => boolean;
11
+ export declare const filterImplementationStructuredPaths: (paths: string[]) => string[];
12
+ export interface SdsImplementationSignals {
13
+ rawSectionHeadings: string[];
14
+ rawFolderEntries: string[];
15
+ sectionHeadings: string[];
16
+ folderEntries: string[];
17
+ skippedHeadingSignals: number;
18
+ skippedFolderSignals: number;
19
+ }
20
+ export declare const collectSdsImplementationSignals: (content: string, options: {
21
+ headingLimit: number;
22
+ folderLimit: number;
23
+ }) => SdsImplementationSignals;
24
+ //# sourceMappingURL=SdsStructureSignals.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SdsStructureSignals.d.ts","sourceRoot":"","sources":["../../../src/services/planning/SdsStructureSignals.ts"],"names":[],"mappings":"AA4GA,eAAO,MAAM,oBAAoB,GAAI,OAAO,MAAM,KAAG,OAA6C,CAAC;AAEnG,eAAO,MAAM,6BAA6B,GAAI,OAAO,MAAM,GAAG,SAAS,KAAG,MAAM,GAAG,SAIlF,CAAC;AAEF,eAAO,MAAM,yBAAyB,GAAI,OAAO,MAAM,KAAG,MAGzD,CAAC;AAEF,eAAO,MAAM,kCAAkC,GAAI,SAAS,MAAM,KAAG,OAgBpE,CAAC;AAEF,eAAO,MAAM,iCAAiC,GAAI,UAAU,MAAM,EAAE,KAAG,MAAM,EAc5E,CAAC;AAEF,eAAO,MAAM,4BAA4B,GAAI,OAAO,MAAM,KAAG,MAAM,GAAG,SA4BrE,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAAI,OAAO,MAAM,KAAG,MAAM,GAAG,SACiC,CAAC;AA8DhG,eAAO,MAAM,sBAAsB,GAAI,SAAS,MAAM,EAAE,OAAO,MAAM,KAAG,MAAM,EA0B7E,CAAC;AAEF,eAAO,MAAM,uBAAuB,GAAI,SAAS,MAAM,EAAE,OAAO,MAAM,KAAG,MAAM,EAsC9E,CAAC;AAaF,eAAO,MAAM,4BAA4B,GAAI,OAAO,MAAM,KAAG,OAiB5D,CAAC;AAEF,eAAO,MAAM,mCAAmC,GAAI,OAAO,MAAM,EAAE,KAAG,MAAM,EAsB3E,CAAC;AAEF,MAAM,WAAW,wBAAwB;IACvC,kBAAkB,EAAE,MAAM,EAAE,CAAC;IAC7B,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,qBAAqB,EAAE,MAAM,CAAC;IAC9B,oBAAoB,EAAE,MAAM,CAAC;CAC9B;AAED,eAAO,MAAM,+BAA+B,GAC1C,SAAS,MAAM,EACf,SAAS;IAAE,YAAY,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,KACrD,wBA2BF,CAAC"}