@rsaglobaltech/specgate 0.27.9 → 1.0.0-rc.2

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 (144) hide show
  1. package/CHANGELOG.md +57 -0
  2. package/dist/packages/core/src/application/ValidateChangeUseCase.js +19 -3
  3. package/dist/packages/core/src/application/ValidateChangeUseCase.js.map +1 -1
  4. package/dist/packages/core/src/domain/ApiContract.js +157 -0
  5. package/dist/packages/core/src/domain/ApiContract.js.map +1 -0
  6. package/dist/packages/core/src/domain/Approvals.js +127 -0
  7. package/dist/packages/core/src/domain/Approvals.js.map +1 -0
  8. package/dist/packages/core/src/domain/ChangeLayers.js +285 -0
  9. package/dist/packages/core/src/domain/ChangeLayers.js.map +1 -0
  10. package/dist/packages/core/src/domain/HarnessConfig.js.map +1 -1
  11. package/dist/packages/core/src/domain/HarnessGaps.js +182 -0
  12. package/dist/packages/core/src/domain/HarnessGaps.js.map +1 -0
  13. package/dist/packages/core/src/domain/HarnessReport.js +16 -1
  14. package/dist/packages/core/src/domain/HarnessReport.js.map +1 -1
  15. package/dist/packages/core/src/domain/HarnessRun.js.map +1 -1
  16. package/dist/packages/core/src/domain/Principles.js +119 -0
  17. package/dist/packages/core/src/domain/Principles.js.map +1 -0
  18. package/dist/packages/core/src/domain/RequirementGraph.js +12 -1
  19. package/dist/packages/core/src/domain/RequirementGraph.js.map +1 -1
  20. package/dist/packages/core/src/domain/Workspace.js +150 -0
  21. package/dist/packages/core/src/domain/Workspace.js.map +1 -0
  22. package/dist/packages/core/src/domain/WorkspaceStory.js +176 -0
  23. package/dist/packages/core/src/domain/WorkspaceStory.js.map +1 -0
  24. package/dist/packages/core/src/index.js +1 -0
  25. package/dist/packages/core/src/index.js.map +1 -1
  26. package/dist/packages/core/src/infrastructure/HarnessConfigFile.js +12 -0
  27. package/dist/packages/core/src/infrastructure/HarnessConfigFile.js.map +1 -1
  28. package/dist/packages/mcp-spec-driven/src/tools.js +18 -0
  29. package/dist/packages/mcp-spec-driven/src/tools.js.map +1 -1
  30. package/dist/scripts/alm/cli.js +45 -4
  31. package/dist/scripts/alm/cli.js.map +1 -1
  32. package/dist/scripts/alm/clients.js +3 -1
  33. package/dist/scripts/alm/clients.js.map +1 -1
  34. package/dist/scripts/alm/phases.js +279 -0
  35. package/dist/scripts/alm/phases.js.map +1 -0
  36. package/dist/scripts/alm/port.js +33 -5
  37. package/dist/scripts/alm/port.js.map +1 -1
  38. package/dist/scripts/alm/providers/azure.js +72 -11
  39. package/dist/scripts/alm/providers/azure.js.map +1 -1
  40. package/dist/scripts/alm/providers/github.js +67 -7
  41. package/dist/scripts/alm/providers/github.js.map +1 -1
  42. package/dist/scripts/alm/providers/index.js +8 -2
  43. package/dist/scripts/alm/providers/index.js.map +1 -1
  44. package/dist/scripts/alm/providers/jira.js +86 -8
  45. package/dist/scripts/alm/providers/jira.js.map +1 -1
  46. package/dist/scripts/alm/providers/linear.js +167 -0
  47. package/dist/scripts/alm/providers/linear.js.map +1 -0
  48. package/dist/scripts/change/artifacts.js +15 -1
  49. package/dist/scripts/change/artifacts.js.map +1 -1
  50. package/dist/scripts/change/instructions.js +47 -5
  51. package/dist/scripts/change/instructions.js.map +1 -1
  52. package/dist/scripts/cli/commands/alm/PhaseCommand.js +153 -0
  53. package/dist/scripts/cli/commands/alm/PhaseCommand.js.map +1 -0
  54. package/dist/scripts/cli/commands/alm/PullCommand.js +33 -2
  55. package/dist/scripts/cli/commands/alm/PullCommand.js.map +1 -1
  56. package/dist/scripts/cli/commands/alm/pull-back.js +104 -0
  57. package/dist/scripts/cli/commands/alm/pull-back.js.map +1 -0
  58. package/dist/scripts/cli/commands/change/ChangeCommand.js +149 -15
  59. package/dist/scripts/cli/commands/change/ChangeCommand.js.map +1 -1
  60. package/dist/scripts/cli/commands/change/TicketCommand.js +20 -7
  61. package/dist/scripts/cli/commands/change/TicketCommand.js.map +1 -1
  62. package/dist/scripts/cli/commands/harness/RunCommand.js +64 -20
  63. package/dist/scripts/cli/commands/harness/RunCommand.js.map +1 -1
  64. package/dist/scripts/cli/commands/project/AdoptCommand.js +44 -4
  65. package/dist/scripts/cli/commands/project/AdoptCommand.js.map +1 -1
  66. package/dist/scripts/cli/commands/project/InitProjectCommand.js +9 -14
  67. package/dist/scripts/cli/commands/project/InitProjectCommand.js.map +1 -1
  68. package/dist/scripts/cli/commands/project/MigrateCommand.js +166 -0
  69. package/dist/scripts/cli/commands/project/MigrateCommand.js.map +1 -0
  70. package/dist/scripts/cli/commands/project/OnboardCommand.js +23 -5
  71. package/dist/scripts/cli/commands/project/OnboardCommand.js.map +1 -1
  72. package/dist/scripts/cli/commands/quality/CheckCommand.js +25 -0
  73. package/dist/scripts/cli/commands/quality/CheckCommand.js.map +1 -1
  74. package/dist/scripts/cli/commands/quality/ValidateSpecsCommand.js +15 -0
  75. package/dist/scripts/cli/commands/quality/ValidateSpecsCommand.js.map +1 -1
  76. package/dist/scripts/cli/commands/spec/ContractCommand.js +117 -0
  77. package/dist/scripts/cli/commands/spec/ContractCommand.js.map +1 -0
  78. package/dist/scripts/cli/commands/spec/DoneCommand.js +22 -0
  79. package/dist/scripts/cli/commands/spec/DoneCommand.js.map +1 -1
  80. package/dist/scripts/cli/commands/spec/DraftCommand.js +22 -8
  81. package/dist/scripts/cli/commands/spec/DraftCommand.js.map +1 -1
  82. package/dist/scripts/cli/commands/spec/DriftCommand.js +128 -0
  83. package/dist/scripts/cli/commands/spec/DriftCommand.js.map +1 -0
  84. package/dist/scripts/cli/commands/spec/StatusCommand.js +85 -0
  85. package/dist/scripts/cli/commands/spec/StatusCommand.js.map +1 -1
  86. package/dist/scripts/cli/commands/spec/StudioCommand.js +48 -6
  87. package/dist/scripts/cli/commands/spec/StudioCommand.js.map +1 -1
  88. package/dist/scripts/cli/commands/workspace/WorkspaceCommand.js +612 -0
  89. package/dist/scripts/cli/commands/workspace/WorkspaceCommand.js.map +1 -0
  90. package/dist/scripts/contract.js +10 -0
  91. package/dist/scripts/contract.js.map +1 -0
  92. package/dist/scripts/docs/nav.js +16 -1
  93. package/dist/scripts/docs/nav.js.map +1 -1
  94. package/dist/scripts/draft/drafting-guide.js +6 -0
  95. package/dist/scripts/draft/drafting-guide.js.map +1 -1
  96. package/dist/scripts/draft/ticket-guide.js +5 -0
  97. package/dist/scripts/draft/ticket-guide.js.map +1 -1
  98. package/dist/scripts/drift.js +10 -0
  99. package/dist/scripts/drift.js.map +1 -0
  100. package/dist/scripts/harness/gap-evidence.js +149 -0
  101. package/dist/scripts/harness/gap-evidence.js.map +1 -0
  102. package/dist/scripts/harness/prompt.js +54 -1
  103. package/dist/scripts/harness/prompt.js.map +1 -1
  104. package/dist/scripts/harness/report.js +104 -5
  105. package/dist/scripts/harness/report.js.map +1 -1
  106. package/dist/scripts/lib/approvals.js +243 -0
  107. package/dist/scripts/lib/approvals.js.map +1 -0
  108. package/dist/scripts/lib/change-review.js +19 -11
  109. package/dist/scripts/lib/change-review.js.map +1 -1
  110. package/dist/scripts/lib/contracts.js +211 -0
  111. package/dist/scripts/lib/contracts.js.map +1 -0
  112. package/dist/scripts/lib/drift.js +80 -0
  113. package/dist/scripts/lib/drift.js.map +1 -0
  114. package/dist/scripts/lib/live-model.js +1 -0
  115. package/dist/scripts/lib/live-model.js.map +1 -1
  116. package/dist/scripts/lib/migrate.js +264 -0
  117. package/dist/scripts/lib/migrate.js.map +1 -0
  118. package/dist/scripts/lib/role-packages.js +230 -0
  119. package/dist/scripts/lib/role-packages.js.map +1 -0
  120. package/dist/scripts/lib/steering.js +180 -0
  121. package/dist/scripts/lib/steering.js.map +1 -0
  122. package/dist/scripts/lib/studio-app-page.js +28 -5
  123. package/dist/scripts/lib/studio-app-page.js.map +1 -1
  124. package/dist/scripts/lib/studio-app.js +29 -0
  125. package/dist/scripts/lib/studio-app.js.map +1 -1
  126. package/dist/scripts/lib/studio-route.js +20 -0
  127. package/dist/scripts/lib/studio-route.js.map +1 -1
  128. package/dist/scripts/lib/surface.js +55 -0
  129. package/dist/scripts/lib/surface.js.map +1 -1
  130. package/dist/scripts/lib/workspace-draft.js +146 -0
  131. package/dist/scripts/lib/workspace-draft.js.map +1 -0
  132. package/dist/scripts/lib/workspace-live-page.js +90 -0
  133. package/dist/scripts/lib/workspace-live-page.js.map +1 -0
  134. package/dist/scripts/lib/workspace-live.js +199 -0
  135. package/dist/scripts/lib/workspace-live.js.map +1 -0
  136. package/dist/scripts/lib/workspace.js +619 -0
  137. package/dist/scripts/lib/workspace.js.map +1 -0
  138. package/dist/scripts/migrate.js +10 -0
  139. package/dist/scripts/migrate.js.map +1 -0
  140. package/dist/scripts/schema/registry.js +12 -0
  141. package/dist/scripts/schema/registry.js.map +1 -1
  142. package/dist/scripts/workspace.js +10 -0
  143. package/dist/scripts/workspace.js.map +1 -0
  144. package/package.json +1 -1
@@ -0,0 +1,119 @@
1
+ "use strict";
2
+ /**
3
+ * The organization's principles (REQ-330..332): `docs/specs/principles.md`,
4
+ * the version a repository follows, and the principles the gate can check.
5
+ *
6
+ * ---
7
+ * principles_version: 1.2.0
8
+ * source: ../workspace/principles.md # or pack:<pack_id>
9
+ * ---
10
+ * ## P1 — No credentials in code
11
+ * <!-- specgate:principle forbid="password\s*=" in="src/**" -->
12
+ *
13
+ * Pure: text in, model out. Reading the source and running the checks is the
14
+ * command layer's.
15
+ */
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.PRINCIPLES_FILE = void 0;
18
+ exports.parsePrinciples = parsePrinciples;
19
+ exports.compareVersions = compareVersions;
20
+ exports.globToRegExp = globToRegExp;
21
+ exports.PRINCIPLES_FILE = "docs/specs/principles.md";
22
+ const HEADING = /^#{2,4}\s+(.+?)\s*$/;
23
+ const PRINCIPLE_COMMENT = /<!--\s*specgate:principle\b([\s\S]*?)-->/;
24
+ /** `key="value with \" escapes"` or `key=value`, as a principle comment writes them. */
25
+ function attributes(body) {
26
+ const out = {};
27
+ const re = /([A-Za-z_][\w-]*)=(?:"((?:[^"\\]|\\.)*)"|(\S+))/g;
28
+ for (const m of body.matchAll(re)) {
29
+ out[m[1].toLowerCase()] = m[2] !== undefined ? m[2].replace(/\\"/g, '"') : m[3];
30
+ }
31
+ return out;
32
+ }
33
+ function frontMatter(text) {
34
+ const m = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?/.exec(text);
35
+ if (!m)
36
+ return { fields: {}, body: text };
37
+ const fields = {};
38
+ for (const line of m[1].split(/\r?\n/)) {
39
+ const kv = /^([A-Za-z_][\w-]*)\s*:\s*(.*?)\s*$/.exec(line);
40
+ if (kv)
41
+ fields[kv[1]] = kv[2].replace(/^["']|["']$/g, "");
42
+ }
43
+ return { fields, body: text.slice(m[0].length) };
44
+ }
45
+ function parsePrinciples(text) {
46
+ const { fields, body } = frontMatter(text);
47
+ const principles = [];
48
+ let current = null;
49
+ for (const line of body.split(/\r?\n/)) {
50
+ const h = HEADING.exec(line);
51
+ if (h) {
52
+ const [, label] = h;
53
+ const idMatch = /^([A-Z][A-Z0-9-]*\d)\b\s*[—:-]?\s*(.*)$/.exec(label);
54
+ current = {
55
+ id: idMatch ? idMatch[1] : label.split(/\s+/)[0],
56
+ title: idMatch ? idMatch[2] || label : label,
57
+ level: "error",
58
+ };
59
+ principles.push(current);
60
+ continue;
61
+ }
62
+ const c = PRINCIPLE_COMMENT.exec(line);
63
+ if (c && current) {
64
+ const a = attributes(c[1]);
65
+ if (a.run)
66
+ current.run = a.run;
67
+ if (a.forbid)
68
+ current.forbid = a.forbid;
69
+ if (a.in)
70
+ current.in = a.in;
71
+ if (a.level === "warn")
72
+ current.level = "warn";
73
+ }
74
+ }
75
+ return {
76
+ version: fields.principles_version || "",
77
+ source: fields.source || "",
78
+ // Only a heading with a rule, or one under the title, is a principle.
79
+ principles: principles.filter((p) => p.run || p.forbid || /^[A-Z][A-Z0-9-]*\d$/.test(p.id)),
80
+ };
81
+ }
82
+ /** -1, 0 or 1, comparing dotted versions numerically (`1.10` after `1.9`). */
83
+ function compareVersions(a, b) {
84
+ const parts = (v) => String(v || "")
85
+ .replace(/^v/, "")
86
+ .split(/[.-]/)
87
+ .map((p) => (/^\d+$/.test(p) ? Number(p) : 0));
88
+ const x = parts(a);
89
+ const y = parts(b);
90
+ for (let i = 0; i < Math.max(x.length, y.length); i++) {
91
+ const d = (x[i] || 0) - (y[i] || 0);
92
+ if (d !== 0)
93
+ return d > 0 ? 1 : -1;
94
+ }
95
+ return 0;
96
+ }
97
+ /** A glob (`src/**`, `*.ts`, `apps/*\/src/**`) as a regular expression on `/` paths. */
98
+ function globToRegExp(glob) {
99
+ let re = "";
100
+ for (let i = 0; i < glob.length; i++) {
101
+ const ch = glob[i];
102
+ if (ch === "*") {
103
+ if (glob[i + 1] === "*") {
104
+ re += ".*";
105
+ i++;
106
+ if (glob[i + 1] === "/")
107
+ i++;
108
+ }
109
+ else
110
+ re += "[^/]*";
111
+ }
112
+ else if (ch === "?")
113
+ re += "[^/]";
114
+ else
115
+ re += ch.replace(/[.+^${}()|[\]\\]/g, "\\$&");
116
+ }
117
+ return new RegExp(`^${re}$`);
118
+ }
119
+ //# sourceMappingURL=Principles.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Principles.js","sourceRoot":"","sources":["../../../../../packages/core/src/domain/Principles.ts"],"names":[],"mappings":"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"}
@@ -51,6 +51,12 @@ class RequirementGraph {
51
51
  dependents;
52
52
  unknown;
53
53
  selfReferential;
54
+ /**
55
+ * REQ-294: `depends=contracts:REQ-003` names a requirement of another
56
+ * repository of the workspace. The repository cannot judge it — the
57
+ * workspace does (`workspace check`) — so it is neither unknown nor an edge.
58
+ */
59
+ external;
54
60
  ids;
55
61
  constructor(requirementIds, declared) {
56
62
  this.ids = requirementIds.map((id) => String(id).toUpperCase());
@@ -63,11 +69,15 @@ class RequirementGraph {
63
69
  }
64
70
  const unknown = [];
65
71
  const selfReferential = [];
72
+ const external = [];
66
73
  for (const [requirement, deps] of Object.entries(declared)) {
67
74
  if (!known.has(requirement))
68
75
  continue; // declared for a REQ not in this project
69
76
  for (const dependency of deps) {
70
- if (dependency === requirement) {
77
+ if (dependency.includes(":")) {
78
+ external.push({ requirement, dependency });
79
+ }
80
+ else if (dependency === requirement) {
71
81
  selfReferential.push(requirement);
72
82
  }
73
83
  else if (!known.has(dependency)) {
@@ -83,6 +93,7 @@ class RequirementGraph {
83
93
  this.dependents = dependents;
84
94
  this.unknown = unknown;
85
95
  this.selfReferential = selfReferential;
96
+ this.external = external;
86
97
  }
87
98
  /** Build from an adjacency map the caller already has — the harness has one. */
88
99
  static fromDependencies(requirementIds, declared) {
@@ -1 +1 @@
1
- {"version":3,"file":"RequirementGraph.js","sourceRoot":"","sources":["../../../../../packages/core/src/domain/RequirementGraph.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"RequirementGraph.js","sourceRoot":"","sources":["../../../../../packages/core/src/domain/RequirementGraph.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;;;AAYH,8CAOC;AARD,sFAAsF;AACtF,SAAgB,iBAAiB,CAAC,GAAW;IAC3C,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC;QACjD,MAAM,EAAE,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QACtC,IAAI,EAAE;YAAE,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACvB,CAAC;IACD,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC;AACnB,CAAC;AAED;;;;;;GAMG;AACH,MAAa,gBAAgB;IAClB,SAAS,CAAqC;IAC9C,UAAU,CAAqC;IAC/C,OAAO,CAA+B;IACtC,eAAe,CAAoB;IAC5C;;;;OAIG;IACM,QAAQ,CAA+B;IAE/B,GAAG,CAAoB;IAExC,YAAoB,cAAiC,EAAE,QAAuB;QAC5E,IAAI,CAAC,GAAG,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;QAChE,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAEhC,MAAM,SAAS,GAA6B,EAAE,CAAC;QAC/C,MAAM,UAAU,GAA6B,EAAE,CAAC;QAChD,KAAK,MAAM,EAAE,IAAI,KAAK,EAAE,CAAC;YACvB,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC;YACnB,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC;QACtB,CAAC;QAED,MAAM,OAAO,GAAwB,EAAE,CAAC;QACxC,MAAM,eAAe,GAAa,EAAE,CAAC;QACrC,MAAM,QAAQ,GAAwB,EAAE,CAAC;QAEzC,KAAK,MAAM,CAAC,WAAW,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC3D,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC;gBAAE,SAAS,CAAC,yCAAyC;YAChF,KAAK,MAAM,UAAU,IAAI,IAAI,EAAE,CAAC;gBAC9B,IAAI,UAAU,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;oBAC7B,QAAQ,CAAC,IAAI,CAAC,EAAE,WAAW,EAAE,UAAU,EAAE,CAAC,CAAC;gBAC7C,CAAC;qBAAM,IAAI,UAAU,KAAK,WAAW,EAAE,CAAC;oBACtC,eAAe,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;gBACpC,CAAC;qBAAM,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC;oBAClC,OAAO,CAAC,IAAI,CAAC,EAAE,WAAW,EAAE,UAAU,EAAE,CAAC,CAAC;gBAC5C,CAAC;qBAAM,CAAC;oBACN,SAAS,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;oBACxC,UAAU,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;gBAC3C,CAAC;YACH,CAAC;QACH,CAAC;QAED,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;QAC7B,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,eAAe,GAAG,eAAe,CAAC;QACvC,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC3B,CAAC;IAED,gFAAgF;IAChF,MAAM,CAAC,gBAAgB,CACrB,cAAiC,EACjC,QAAuB;QAEvB,OAAO,IAAI,gBAAgB,CAAC,cAAc,EAAE,QAAQ,CAAC,CAAC;IACxD,CAAC;IAED;;;;;;;;OAQG;IACH,IAAI,QAAQ;QACV,MAAM,SAAS,GAAG,IAAI,GAAG,CACvB,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAC9D,CAAC;QAEF,MAAM,KAAK,GAAa,EAAE,CAAC;QAC3B,MAAM,MAAM,GAAe,EAAE,CAAC;QAE9B,OAAO,SAAS,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;YAC1B,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,IAAI,KAAK,CAAC,CAAC,CAAC;YACrE,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;gBAAE,MAAM,CAAC,4CAA4C;YAE3E,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACnB,KAAK,MAAM,EAAE,IAAI,KAAK,EAAE,CAAC;gBACvB,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;gBACf,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YACvB,CAAC;YACD,KAAK,MAAM,IAAI,IAAI,SAAS,CAAC,MAAM,EAAE,EAAE,CAAC;gBACtC,KAAK,MAAM,EAAE,IAAI,KAAK;oBAAE,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YAC1C,CAAC;QACH,CAAC;QAED,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IAC3B,CAAC;IAED,IAAI,KAAK;QACP,OAAO,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;IAC7B,CAAC;IAED,IAAI,MAAM;QACR,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC;IAC9B,CAAC;IAED;;;;;OAKG;IACH,IAAI,MAAM;QACR,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACpC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;QACxD,OAAO,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;IAChC,CAAC;IAED;;;OAGG;IACH,oBAAoB,CAAC,WAAmB;QACtC,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;QAClC,IAAI,IAAI,GAAG,IAAI,CAAC;QAChB,OAAO,IAAI,EAAE,CAAC;YACZ,IAAI,GAAG,KAAK,CAAC;YACb,KAAK,MAAM,CAAC,EAAE,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;gBACxD,IAAI,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;oBAAE,SAAS;gBAC9B,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,WAAW,IAAI,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;oBAC1D,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;oBAChB,IAAI,GAAG,IAAI,CAAC;gBACd,CAAC;YACH,CAAC;QACH,CAAC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,0EAA0E;IAClE,UAAU,CAAC,KAAwB;QACzC,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC;QAC/B,MAAM,MAAM,GAAe,EAAE,CAAC;QAC9B,MAAM,aAAa,GAAG,IAAI,GAAG,EAAU,CAAC;QACxC,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;QAC/B,MAAM,IAAI,GAAa,EAAE,CAAC;QAE1B,MAAM,KAAK,GAAG,CAAC,EAAU,EAAQ,EAAE;YACjC,IAAI,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;gBAAE,OAAO;YAEzB,MAAM,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;YAC5B,IAAI,EAAE,KAAK,CAAC,CAAC,EAAE,CAAC;gBACd,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,aAAa,CAAC,CAAC;gBACxD,OAAO;YACT,CAAC;YAED,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACd,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC;gBAC3C,IAAI,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC;oBAAE,KAAK,CAAC,GAAG,CAAC,CAAC;YACnC,CAAC;YACD,IAAI,CAAC,GAAG,EAAE,CAAC;YACX,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACf,CAAC,CAAC;QAEF,KAAK,MAAM,EAAE,IAAI,KAAK;YAAE,KAAK,CAAC,EAAE,CAAC,CAAC;QAClC,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,sFAAsF;IAC9E,WAAW,CAAC,KAAe,EAAE,MAAkB,EAAE,IAAiB;QACxE,MAAM,QAAQ,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QACtC,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QACtC,MAAM,UAAU,GAAG,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC;QACrE,MAAM,SAAS,GAAG,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACvC,IAAI,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC;YAAE,OAAO;QAChC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACpB,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAC1B,CAAC;CACF;AA7KD,4CA6KC"}
@@ -0,0 +1,150 @@
1
+ "use strict";
2
+ /**
3
+ * A workspace: the repositories of one product, named in one file (ADR-0041).
4
+ *
5
+ * Specgate's gate is a repository's. A product made of services, a web app and
6
+ * a contracts repository needs a place that knows them all: which repositories
7
+ * there are, which requirement of one another depends on, and which business
8
+ * story is split into a change in each. That place is a workspace repository
9
+ * holding `specgate.workspace.yaml`. Inside a member, `REQ-012` stays the id;
10
+ * across the workspace it is `fleet:REQ-012`.
11
+ *
12
+ * Pure domain: parsing and the id grammar. Reading the members is
13
+ * `scripts/lib/workspace.ts`.
14
+ */
15
+ Object.defineProperty(exports, "__esModule", { value: true });
16
+ exports.REPO_NAME = exports.WORKSPACE_ROLES = exports.STORIES_DIR = exports.WORKSPACE_FILE = void 0;
17
+ exports.qualifiedRefs = qualifiedRefs;
18
+ exports.splitQualified = splitQualified;
19
+ exports.readWorkspace = readWorkspace;
20
+ exports.renderWorkspace = renderWorkspace;
21
+ exports.readStory = readStory;
22
+ exports.renderStory = renderStory;
23
+ const YamlLite_1 = require("./YamlLite");
24
+ exports.WORKSPACE_FILE = "specgate.workspace.yaml";
25
+ /** Where a workspace keeps its business stories. */
26
+ exports.STORIES_DIR = "docs/stories";
27
+ /** What a member is to the product. `contracts` holds the APIs others depend on. */
28
+ exports.WORKSPACE_ROLES = ["service", "web", "library", "contracts"];
29
+ /** A member name: what a qualified id can carry before its colon. */
30
+ exports.REPO_NAME = /^[a-z][a-z0-9-]*$/;
31
+ /** `fleet:REQ-012` anywhere in a text. */
32
+ const QUALIFIED_ID = /(?<![\w./-])([a-z][a-z0-9-]*):(REQ-\d+)\b/g;
33
+ /** Every qualified id a text mentions, with its line (1-based). */
34
+ function qualifiedRefs(text) {
35
+ const out = [];
36
+ const lines = text.split(/\r?\n/);
37
+ lines.forEach((line, i) => {
38
+ for (const m of line.matchAll(QUALIFIED_ID))
39
+ out.push({ repo: m[1], id: m[2], line: i + 1 });
40
+ });
41
+ return out;
42
+ }
43
+ /**
44
+ * `contracts:REQ-003` as a `depends=` entry reads it, upper-cased by
45
+ * `splitDependencies`: the repository and the id, or null for a plain id.
46
+ */
47
+ function splitQualified(dep) {
48
+ const m = /^([A-Za-z][A-Za-z0-9-]*):(REQ-\d+)$/i.exec(dep.trim());
49
+ return m ? { repo: m[1].toLowerCase(), id: m[2].toUpperCase() } : null;
50
+ }
51
+ /** The workspace file, checked: every member named once, with a path and a known role. */
52
+ function readWorkspace(text) {
53
+ const problems = [];
54
+ let doc;
55
+ try {
56
+ doc = (0, YamlLite_1.parseYamlLite)(text) || {};
57
+ }
58
+ catch (e) {
59
+ return {
60
+ config: null,
61
+ problems: [`${exports.WORKSPACE_FILE} does not parse: ${e.message}`],
62
+ };
63
+ }
64
+ const version = doc.workspace_version;
65
+ if (version !== 1 && version !== "1") {
66
+ problems.push(`${exports.WORKSPACE_FILE} needs workspace_version: 1.`);
67
+ }
68
+ const name = String(doc.name || "").trim();
69
+ if (!name)
70
+ problems.push(`${exports.WORKSPACE_FILE} needs a name.`);
71
+ const rawRepos = Array.isArray(doc.repos) ? doc.repos : [];
72
+ if (rawRepos.length === 0)
73
+ problems.push(`${exports.WORKSPACE_FILE} lists no repos.`);
74
+ const repos = [];
75
+ const seen = new Set();
76
+ for (const raw of rawRepos) {
77
+ const repoName = String((raw && raw.name) || "").trim();
78
+ if (!exports.REPO_NAME.test(repoName)) {
79
+ problems.push(`A repo is named "${repoName}": a name is lower-case letters, digits and dashes, as in fleet.`);
80
+ continue;
81
+ }
82
+ if (seen.has(repoName)) {
83
+ problems.push(`The repo ${repoName} is listed twice.`);
84
+ continue;
85
+ }
86
+ seen.add(repoName);
87
+ const repoPath = String(raw.path || "").trim();
88
+ if (!repoPath)
89
+ problems.push(`The repo ${repoName} has no path.`);
90
+ const role = String(raw.role || "service").trim();
91
+ if (!exports.WORKSPACE_ROLES.includes(role)) {
92
+ problems.push(`The repo ${repoName} has the role ${role}: a role is ${exports.WORKSPACE_ROLES.join(", ")}.`);
93
+ }
94
+ const caps = raw.capabilities;
95
+ repos.push({
96
+ name: repoName,
97
+ path: repoPath,
98
+ ...(raw.url ? { url: String(raw.url) } : {}),
99
+ role,
100
+ capabilities: Array.isArray(caps) ? caps.map(String) : caps ? [String(caps)] : [],
101
+ });
102
+ }
103
+ return { config: problems.length ? null : { name, repos }, problems };
104
+ }
105
+ /** The workspace file as `workspace init` writes it. */
106
+ function renderWorkspace(config) {
107
+ const lines = [
108
+ "# The repositories of one product (ADR-0041). Across them a requirement is",
109
+ "# <repo>:REQ-NNN; inside a repository REQ-NNN stays its id.",
110
+ "workspace_version: 1",
111
+ `name: ${config.name}`,
112
+ "repos:",
113
+ ];
114
+ for (const r of config.repos) {
115
+ lines.push(` - name: ${r.name}`, ` path: ${r.path}`);
116
+ if (r.url)
117
+ lines.push(` url: ${r.url}`);
118
+ lines.push(` role: ${r.role}`);
119
+ lines.push(` capabilities: [${r.capabilities.join(", ")}]`);
120
+ }
121
+ return lines.join("\n") + "\n";
122
+ }
123
+ /** `story.yaml` of a workspace story. */
124
+ function readStory(text) {
125
+ let doc;
126
+ try {
127
+ doc = (0, YamlLite_1.parseYamlLite)(text) || {};
128
+ }
129
+ catch {
130
+ return null;
131
+ }
132
+ const id = String(doc.story || "").trim();
133
+ if (!id)
134
+ return null;
135
+ const subs = Array.isArray(doc.subchanges) ? doc.subchanges : [];
136
+ return {
137
+ id,
138
+ title: String(doc.title || id),
139
+ subchanges: subs
140
+ .map((s) => ({ repo: String(s.repo || ""), change: String(s.change || id) }))
141
+ .filter((s) => s.repo),
142
+ };
143
+ }
144
+ function renderStory(story) {
145
+ const lines = ["story_version: 1", `story: ${story.id}`, `title: ${story.title}`, "subchanges:"];
146
+ for (const s of story.subchanges)
147
+ lines.push(` - repo: ${s.repo}`, ` change: ${s.change}`);
148
+ return lines.join("\n") + "\n";
149
+ }
150
+ //# sourceMappingURL=Workspace.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Workspace.js","sourceRoot":"","sources":["../../../../../packages/core/src/domain/Workspace.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;GAYG;;;AAyCH,sCAOC;AAMD,wCAGC;AAQD,sCAoDC;AAGD,0CAeC;AAeD,8BAiBC;AAED,kCAIC;AA3KD,yCAA2C;AAE9B,QAAA,cAAc,GAAG,yBAAyB,CAAC;AAExD,oDAAoD;AACvC,QAAA,WAAW,GAAG,cAAc,CAAC;AAE1C,oFAAoF;AACvE,QAAA,eAAe,GAAG,CAAC,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,WAAW,CAAU,CAAC;AAkBnF,qEAAqE;AACxD,QAAA,SAAS,GAAG,mBAAmB,CAAC;AAE7C,0CAA0C;AAC1C,MAAM,YAAY,GAAG,4CAA4C,CAAC;AAQlE,mEAAmE;AACnE,SAAgB,aAAa,CAAC,IAAY;IACxC,MAAM,GAAG,GAAmB,EAAE,CAAC;IAC/B,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAClC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE;QACxB,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC;YAAE,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAC/F,CAAC,CAAC,CAAC;IACH,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;GAGG;AACH,SAAgB,cAAc,CAAC,GAAW;IACxC,MAAM,CAAC,GAAG,sCAAsC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;IAClE,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AACzE,CAAC;AAOD,0FAA0F;AAC1F,SAAgB,aAAa,CAAC,IAAY;IACxC,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,IAAI,GAA4B,CAAC;IACjC,IAAI,CAAC;QACH,GAAG,GAAG,IAAA,wBAAa,EAAC,IAAI,CAAC,IAAI,EAAE,CAAC;IAClC,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO;YACL,MAAM,EAAE,IAAI;YACZ,QAAQ,EAAE,CAAC,GAAG,sBAAc,oBAAqB,CAAW,CAAC,OAAO,EAAE,CAAC;SACxE,CAAC;IACJ,CAAC;IACD,MAAM,OAAO,GAAG,GAAG,CAAC,iBAAiB,CAAC;IACtC,IAAI,OAAO,KAAK,CAAC,IAAI,OAAO,KAAK,GAAG,EAAE,CAAC;QACrC,QAAQ,CAAC,IAAI,CAAC,GAAG,sBAAc,8BAA8B,CAAC,CAAC;IACjE,CAAC;IACD,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IAC3C,IAAI,CAAC,IAAI;QAAE,QAAQ,CAAC,IAAI,CAAC,GAAG,sBAAc,gBAAgB,CAAC,CAAC;IAC5D,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;IAC3D,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,QAAQ,CAAC,IAAI,CAAC,GAAG,sBAAc,kBAAkB,CAAC,CAAC;IAC9E,MAAM,KAAK,GAAoB,EAAE,CAAC;IAClC,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,KAAK,MAAM,GAAG,IAAI,QAA0C,EAAE,CAAC;QAC7D,MAAM,QAAQ,GAAG,MAAM,CAAC,CAAC,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QACxD,IAAI,CAAC,iBAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC9B,QAAQ,CAAC,IAAI,CACX,oBAAoB,QAAQ,kEAAkE,CAC/F,CAAC;YACF,SAAS;QACX,CAAC;QACD,IAAI,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;YACvB,QAAQ,CAAC,IAAI,CAAC,YAAY,QAAQ,mBAAmB,CAAC,CAAC;YACvD,SAAS;QACX,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACnB,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QAC/C,IAAI,CAAC,QAAQ;YAAE,QAAQ,CAAC,IAAI,CAAC,YAAY,QAAQ,eAAe,CAAC,CAAC;QAClE,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,IAAI,SAAS,CAAC,CAAC,IAAI,EAAmB,CAAC;QACnE,IAAI,CAAC,uBAAe,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YACpC,QAAQ,CAAC,IAAI,CACX,YAAY,QAAQ,iBAAiB,IAAI,eAAe,uBAAe,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CACtF,CAAC;QACJ,CAAC;QACD,MAAM,IAAI,GAAG,GAAG,CAAC,YAAY,CAAC;QAC9B,KAAK,CAAC,IAAI,CAAC;YACT,IAAI,EAAE,QAAQ;YACd,IAAI,EAAE,QAAQ;YACd,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC5C,IAAI;YACJ,YAAY,EAAE,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;SAClF,CAAC,CAAC;IACL,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,QAAQ,EAAE,CAAC;AACxE,CAAC;AAED,wDAAwD;AACxD,SAAgB,eAAe,CAAC,MAAuB;IACrD,MAAM,KAAK,GAAG;QACZ,4EAA4E;QAC5E,6DAA6D;QAC7D,sBAAsB;QACtB,SAAS,MAAM,CAAC,IAAI,EAAE;QACtB,QAAQ;KACT,CAAC;IACF,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;QAC7B,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,IAAI,EAAE,EAAE,aAAa,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QACzD,IAAI,CAAC,CAAC,GAAG;YAAE,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;QAC3C,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QAClC,KAAK,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACjE,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;AACjC,CAAC;AAcD,yCAAyC;AACzC,SAAgB,SAAS,CAAC,IAAY;IACpC,IAAI,GAA4B,CAAC;IACjC,IAAI,CAAC;QACH,GAAG,GAAG,IAAA,wBAAa,EAAC,IAAI,CAAC,IAAI,EAAE,CAAC;IAClC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,EAAE,GAAG,MAAM,CAAC,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IAC1C,IAAI,CAAC,EAAE;QAAE,OAAO,IAAI,CAAC;IACrB,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;IACjE,OAAO;QACL,EAAE;QACF,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC;QAC9B,UAAU,EAAG,IAAuC;aACjD,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,MAAM,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC;aAC5E,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;KACzB,CAAC;AACJ,CAAC;AAED,SAAgB,WAAW,CAAC,KAAY;IACtC,MAAM,KAAK,GAAG,CAAC,kBAAkB,EAAE,UAAU,KAAK,CAAC,EAAE,EAAE,EAAE,UAAU,KAAK,CAAC,KAAK,EAAE,EAAE,aAAa,CAAC,CAAC;IACjG,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,UAAU;QAAE,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,IAAI,EAAE,EAAE,eAAe,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;IAC/F,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;AACjC,CAAC"}
@@ -0,0 +1,176 @@
1
+ "use strict";
2
+ /**
3
+ * A workspace story as text: the stories a workspace brief names, the
4
+ * sections of a `story.md`, and the names a workspace gives its repositories
5
+ * (REQ-339..348). Pure; reading and writing the files is `scripts/lib`.
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.CRITERIA = exports.INTENT = void 0;
9
+ exports.briefFrontMatter = briefFrontMatter;
10
+ exports.briefText = briefText;
11
+ exports.briefStories = briefStories;
12
+ exports.workspaceBriefTemplate = workspaceBriefTemplate;
13
+ exports.section = section;
14
+ exports.criteriaLines = criteriaLines;
15
+ exports.storyTemplate = storyTemplate;
16
+ exports.shortNames = shortNames;
17
+ const FRONT = /^---\r?\n([\s\S]*?)\r?\n---[ \t]*(?:\r?\n|$)/;
18
+ /** The YAML between a brief's leading `---` lines, or null. */
19
+ function briefFrontMatter(text) {
20
+ const m = FRONT.exec(text);
21
+ return m ? m[1] : null;
22
+ }
23
+ /** Everything after the front matter. */
24
+ function briefText(text) {
25
+ const m = FRONT.exec(text);
26
+ return (m ? text.slice(m[0].length) : text).replace(/^(?:[ \t]*\r?\n)+/, "");
27
+ }
28
+ /** `a, b, [c, d]` split on the commas outside brackets. */
29
+ function topLevel(s) {
30
+ const out = [];
31
+ let depth = 0;
32
+ let cur = "";
33
+ for (const ch of s) {
34
+ if (ch === "[")
35
+ depth += 1;
36
+ if (ch === "]")
37
+ depth -= 1;
38
+ if (ch === "," && depth === 0) {
39
+ out.push(cur);
40
+ cur = "";
41
+ }
42
+ else
43
+ cur += ch;
44
+ }
45
+ if (cur.trim())
46
+ out.push(cur);
47
+ return out.map((x) => x.trim()).filter(Boolean);
48
+ }
49
+ const unquote = (s) => s.trim().replace(/^(["'])(.*)\1$/, "$2");
50
+ /**
51
+ * The stories of a workspace brief's front matter (REQ-339):
52
+ *
53
+ * stories:
54
+ * - { id: follow-shipment, title: El cliente sigue su envío, repos: [fleet, tracking] }
55
+ */
56
+ function briefStories(frontMatter) {
57
+ if (!frontMatter)
58
+ return [];
59
+ const lines = frontMatter.split(/\r?\n/);
60
+ const start = lines.findIndex((l) => /^stories:/.test(l));
61
+ if (start < 0)
62
+ return [];
63
+ const out = [];
64
+ for (const line of lines.slice(start + 1)) {
65
+ if (/^\S/.test(line))
66
+ break;
67
+ const m = /^\s*-\s*\{(.*)\}\s*$/.exec(line);
68
+ if (!m)
69
+ continue;
70
+ const fields = {};
71
+ for (const part of topLevel(m[1])) {
72
+ const kv = /^([a-z_]+)\s*:\s*(.*)$/.exec(part);
73
+ if (kv)
74
+ fields[kv[1]] = kv[2].trim();
75
+ }
76
+ const id = unquote(fields.id || "");
77
+ if (!/^[a-z0-9][a-z0-9-]*$/.test(id))
78
+ continue;
79
+ const repos = /^\[(.*)\]$/.exec(fields.repos || "");
80
+ out.push({
81
+ id,
82
+ title: unquote(fields.title || "") || id.replace(/-/g, " "),
83
+ repos: repos
84
+ ? repos[1]
85
+ .split(",")
86
+ .map((r) => unquote(r))
87
+ .filter(Boolean)
88
+ : [],
89
+ });
90
+ }
91
+ return out;
92
+ }
93
+ /** The front matter `workspace draft` writes above a client's brief. */
94
+ function workspaceBriefTemplate(product, repos) {
95
+ return [
96
+ "---",
97
+ `product: ${product}`,
98
+ "# The business stories of the brief, each split across the repositories it",
99
+ "# touches: `specgate workspace draft <id>` drafts one, `workspace propose <id>`",
100
+ "# opens its change in each repository (REQ-339).",
101
+ `# e.g. - { id: follow-shipment, title: The client follows a shipment, repos: [${repos.slice(0, 2).join(", ")}] }`,
102
+ "stories: []",
103
+ "---",
104
+ "",
105
+ ].join("\n");
106
+ }
107
+ /** A `##` section of a Markdown text, without its comments, or "". */
108
+ function section(md, heading) {
109
+ const lines = md.split(/\r?\n/);
110
+ const at = lines.findIndex((l) => /^##\s/.test(l) && heading.test(l));
111
+ if (at < 0)
112
+ return "";
113
+ const body = [];
114
+ for (const l of lines.slice(at + 1)) {
115
+ if (/^##\s/.test(l))
116
+ break;
117
+ body.push(l);
118
+ }
119
+ return body
120
+ .join("\n")
121
+ .replace(/<!--[\s\S]*?-->/g, "")
122
+ .trim();
123
+ }
124
+ exports.INTENT = /intent|intenci[oó]n|context/i;
125
+ exports.CRITERIA = /acceptance criteria|criterios de aceptaci[oó]n|akzeptanzkriterien/i;
126
+ /** A story's (or a Discover's) `AC-n` lines, as written. */
127
+ function criteriaLines(md) {
128
+ return section(md, exports.CRITERIA)
129
+ .split(/\r?\n/)
130
+ .map((l) => l.trim())
131
+ .filter((l) => /^[-*]\s*AC-\d+\s*[:—–-]\s*\S/.test(l))
132
+ .map((l) => l.replace(/^[-*]\s*/, "").replace(/\s+/g, " "));
133
+ }
134
+ /** The `story.md` `workspace draft <id>` writes for a person, or an agent, to fill. */
135
+ function storyTemplate(title, repos) {
136
+ return [
137
+ `# Story: ${title}`,
138
+ "",
139
+ "## Intent",
140
+ "",
141
+ "<!-- The business story, in the words of whoever asked for it: who needs what, and why. It stays as it is while each repository's change works out the how. -->",
142
+ "",
143
+ "## Acceptance criteria",
144
+ "",
145
+ "<!-- One line each, numbered: every repository's design answers the ones it touches. -->",
146
+ "- AC-1:",
147
+ "",
148
+ "## Repositories",
149
+ "",
150
+ ...repos.map((r) => `- \`${r}\``),
151
+ "",
152
+ ].join("\n");
153
+ }
154
+ /**
155
+ * The names a workspace gives sibling folders: without the prefix they all
156
+ * share (`truck-flote-fleet`, `truck-flote-web` → `fleet`, `web`), so ids read
157
+ * `fleet:REQ-012` (REQ-348). Unchanged when stripping would leave a name empty
158
+ * or two names equal.
159
+ */
160
+ function shortNames(names) {
161
+ if (names.length < 2)
162
+ return names;
163
+ let prefix = names[0];
164
+ for (const n of names.slice(1)) {
165
+ while (prefix && !n.startsWith(prefix))
166
+ prefix = prefix.slice(0, -1);
167
+ }
168
+ const cut = prefix.lastIndexOf("-");
169
+ if (cut < 0)
170
+ return names;
171
+ const keep = prefix.slice(0, cut + 1);
172
+ const short = names.map((n) => n.slice(keep.length));
173
+ const valid = short.every((s) => /^[a-z][a-z0-9-]*$/.test(s));
174
+ return valid && new Set(short).size === short.length ? short : names;
175
+ }
176
+ //# sourceMappingURL=WorkspaceStory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WorkspaceStory.js","sourceRoot":"","sources":["../../../../../packages/core/src/domain/WorkspaceStory.ts"],"names":[],"mappings":"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"}
@@ -26,6 +26,7 @@ exports.safeResolve = exports.resetWrittenFiles = exports.getWrittenFiles = expo
26
26
  // ── Domain ───────────────────────────────────────────────────────────────────
27
27
  __exportStar(require("./domain/ArchivePlan"), exports);
28
28
  __exportStar(require("./domain/ChangeTemplates"), exports);
29
+ __exportStar(require("./domain/ChangeLayers"), exports);
29
30
  __exportStar(require("./domain/DeltaSpec"), exports);
30
31
  __exportStar(require("./domain/CucumberMessages"), exports);
31
32
  __exportStar(require("./domain/DeclaredArtifacts"), exports);
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../packages/core/src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;GAOG;;;;;;;;;;;;;;;;;AAEH,gFAAgF;AAChF,uDAAqC;AACrC,2DAAyC;AACzC,qDAAmC;AACnC,4DAA0C;AAC1C,6DAA2C;AAC3C,wDAAsC;AACtC,sDAAoC;AACpC,sDAAoC;AACpC,yDAAuC;AACvC,mDAAiC;AACjC,2DAAyC;AACzC,0DAAwC;AACxC,uDAAqC;AACrC,qDAAmC;AACnC,yDAAuC;AACvC,yDAAuC;AACvC,sDAAoC;AACpC,oDAAkC;AAClC,oDAAkC;AAClC,4DAA0C;AAC1C,qDAAmC;AACnC,oDAAkC;AAClC,0DAAwC;AACxC,wDAAsC;AACtC,4DAA0C;AAC1C,qDAAmC;AACnC,2DAAyC;AACzC,gEAA8C;AAC9C,6DAA2C;AAC3C,uDAAqC;AACrC,oDAAkC;AAClC,sDAAoC;AACpC,sDAAoC;AACpC,2DAAyC;AACzC,8DAA4C;AAC5C,6DAA2C;AAC3C,8DAA4C;AAC5C,4DAA0C;AAC1C,4DAA0C;AAC1C,oDAAkC;AAElC,gFAAgF;AAChF,4EAA0D;AAC1D,+EAA6D;AAC7D,yEAAuD;AACvD,kFAAgE;AAChE,8EAA4D;AAY5D,gFAAgF;AAChF,sEAAoD;AACpD,qEAAmD;AACnD,wEAAsD;AACtD,2EAAyD;AACzD,oEAAkD;AAClD,uEAAqD;AACrD,kEAAgD;AAChD,+EAA6D;AAC7D,sEAAoD;AACpD,uEAAqD;AAErD,gFAAgF;AAChF,mEAAiD;AACjD,mEAAiD;AACjD,qEAAmD;AACnD,yEAAuD;AACvD,4EAA0D;AAC1D,+EAA6D;AAC7D,0EAAwD;AACxD,kEAAgD;AAChD,qEAAmD;AACnD,0EAA0E;AAC1E,gFAAgF;AAChF,wEAI4C;AAH1C,wHAAA,WAAW,OAAuB;AAClC,sHAAA,UAAU,OAAqB;AAC/B,kHAAA,aAAa,OAAA;AAEf,0EAAwD;AACxD,0EAAwD;AACxD,2EAAyD;AACzD,+EAA+E;AAC/E,oEAAoE;AACpE,0EAAmG;AAA1F,6HAAA,iBAAiB,OAA2B;AACrD,0EAQ6C;AAP3C,8GAAA,QAAQ,OAAA;AACR,sHAAA,gBAAgB,OAAA;AAChB,kHAAA,YAAY,OAAA;AACZ,+GAAA,SAAS,OAAA;AACT,qHAAA,eAAe,OAAA;AACf,uHAAA,iBAAiB,OAAA;AACjB,iHAAA,WAAW,OAAA;AAEb,yEAAuD;AACvD,kFAAgE;AAChE,8EAA4D;AAC5D,qEAAmD;AACnD,sEAAoD"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../packages/core/src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;GAOG;;;;;;;;;;;;;;;;;AAEH,gFAAgF;AAChF,uDAAqC;AACrC,2DAAyC;AACzC,wDAAsC;AACtC,qDAAmC;AACnC,4DAA0C;AAC1C,6DAA2C;AAC3C,wDAAsC;AACtC,sDAAoC;AACpC,sDAAoC;AACpC,yDAAuC;AACvC,mDAAiC;AACjC,2DAAyC;AACzC,0DAAwC;AACxC,uDAAqC;AACrC,qDAAmC;AACnC,yDAAuC;AACvC,yDAAuC;AACvC,sDAAoC;AACpC,oDAAkC;AAClC,oDAAkC;AAClC,4DAA0C;AAC1C,qDAAmC;AACnC,oDAAkC;AAClC,0DAAwC;AACxC,wDAAsC;AACtC,4DAA0C;AAC1C,qDAAmC;AACnC,2DAAyC;AACzC,gEAA8C;AAC9C,6DAA2C;AAC3C,uDAAqC;AACrC,oDAAkC;AAClC,sDAAoC;AACpC,sDAAoC;AACpC,2DAAyC;AACzC,8DAA4C;AAC5C,6DAA2C;AAC3C,8DAA4C;AAC5C,4DAA0C;AAC1C,4DAA0C;AAC1C,oDAAkC;AAElC,gFAAgF;AAChF,4EAA0D;AAC1D,+EAA6D;AAC7D,yEAAuD;AACvD,kFAAgE;AAChE,8EAA4D;AAY5D,gFAAgF;AAChF,sEAAoD;AACpD,qEAAmD;AACnD,wEAAsD;AACtD,2EAAyD;AACzD,oEAAkD;AAClD,uEAAqD;AACrD,kEAAgD;AAChD,+EAA6D;AAC7D,sEAAoD;AACpD,uEAAqD;AAErD,gFAAgF;AAChF,mEAAiD;AACjD,mEAAiD;AACjD,qEAAmD;AACnD,yEAAuD;AACvD,4EAA0D;AAC1D,+EAA6D;AAC7D,0EAAwD;AACxD,kEAAgD;AAChD,qEAAmD;AACnD,0EAA0E;AAC1E,gFAAgF;AAChF,wEAI4C;AAH1C,wHAAA,WAAW,OAAuB;AAClC,sHAAA,UAAU,OAAqB;AAC/B,kHAAA,aAAa,OAAA;AAEf,0EAAwD;AACxD,0EAAwD;AACxD,2EAAyD;AACzD,+EAA+E;AAC/E,oEAAoE;AACpE,0EAAmG;AAA1F,6HAAA,iBAAiB,OAA2B;AACrD,0EAQ6C;AAP3C,8GAAA,QAAQ,OAAA;AACR,sHAAA,gBAAgB,OAAA;AAChB,kHAAA,YAAY,OAAA;AACZ,+GAAA,SAAS,OAAA;AACT,qHAAA,eAAe,OAAA;AACf,uHAAA,iBAAiB,OAAA;AACjB,iHAAA,WAAW,OAAA;AAEb,yEAAuD;AACvD,kFAAgE;AAChE,8EAA4D;AAC5D,qEAAmD;AACnD,sEAAoD"}
@@ -102,6 +102,11 @@ const KNOWN_KEYS = new Set([
102
102
  "mutation_score",
103
103
  "checks",
104
104
  "commit_types",
105
+ // REQ-334: behaviour changed without a specification — reported, or a gate.
106
+ "drift",
107
+ // ADR-0043: who holds each role, and which layers need their approvals.
108
+ "roles",
109
+ "approvals",
105
110
  ]);
106
111
  function readHarnessConfig(projectDir) {
107
112
  const filePath = path.join(projectDir, exports.HARNESS_CONFIG_FILE);
@@ -208,6 +213,13 @@ function readHarnessConfig(projectDir) {
208
213
  // run Cucumber, and there is no way to know from here).
209
214
  if (parsed.e2e_dir !== undefined)
210
215
  config.e2eDir = String(parsed.e2e_dir).trim();
216
+ if (parsed.drift !== undefined) {
217
+ const drift = String(parsed.drift).trim();
218
+ if (drift !== "report" && drift !== "gate" && drift !== "off") {
219
+ throw new Error(`${exports.HARNESS_CONFIG_FILE}: drift must be report, gate or off, not ${drift}.`);
220
+ }
221
+ config.drift = drift;
222
+ }
211
223
  if (parsed.message_report !== undefined) {
212
224
  config.messageReport = String(parsed.message_report);
213
225
  }