@sdd-method/author-cli 0.9.0 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -218,6 +218,16 @@ const ManifestSchema = z.object({
218
218
  // Shared-library trait (sdd-manifest-schema 1.12.0, M-ADR 0217 §4.4). Profile-agnostic,
219
219
  // like `exemplar`; absent is the unmarked norm, no finding.
220
220
  shared_library: z.boolean().optional(),
221
+ // Where this estate's journey behaviour is mastered (sdd-manifest-schema 1.13.0, M-ADR 0229 §4.2, Proposed).
222
+ // `master` is declared at the root, and journey-impact treats a member naming its platform as inheriting it.
223
+ // `test_paths` is never inherited: it is relative to this SDD, so an SDD that holds end-to-end files declares
224
+ // its own block, with the master and its paths. Unknown values fail at load.
225
+ journeys: z
226
+ .object({
227
+ master: z.enum(["test-file", "store"]),
228
+ test_paths: z.array(z.string()).optional(),
229
+ })
230
+ .optional(),
221
231
  // Application-product archetype trait (M-ADR 0191, sdd-manifest-schema
222
232
  // 1.2.0). RESOLVED enum, not fixed: the loader validates only the slug
223
233
  // shape here. Whether the value resolves against the active vocabulary
@@ -378,6 +388,9 @@ export async function loadSddManifest(sddPath, options) {
378
388
  ...(parsed.data.packaging !== undefined ? { packaging: parsed.data.packaging } : {}),
379
389
  ...(parsed.data.exemplar !== undefined ? { exemplar: parsed.data.exemplar } : {}),
380
390
  ...(parsed.data.shared_library !== undefined ? { sharedLibrary: parsed.data.shared_library } : {}),
391
+ ...(parsed.data.journeys !== undefined
392
+ ? { journeys: { master: parsed.data.journeys.master, testPaths: parsed.data.journeys.test_paths ?? [] } }
393
+ : {}),
381
394
  ...(parsed.data.application_archetype !== undefined
382
395
  ? { applicationArchetype: parsed.data.application_archetype }
383
396
  : {}),
@@ -933,3 +933,21 @@ coverage:
933
933
  kind: enum
934
934
  scoring: not-applicable
935
935
  reason: closed vocabulary, not an artefact
936
+ feature_status:
937
+ kind: enum
938
+ scoring: not-applicable
939
+ reason: closed vocabulary, not an artefact
940
+ journey_requirement:
941
+ kind: edge
942
+ scoring: derived-edge
943
+ class: dependency
944
+ impact_flow: toward-source
945
+ reason: derived from end-to-end test tags or journey features' living specs
946
+ feature_kind:
947
+ kind: enum
948
+ scoring: not-applicable
949
+ reason: closed vocabulary, not an artefact
950
+ journey_requirement_basis:
951
+ kind: enum
952
+ scoring: not-applicable
953
+ reason: closed vocabulary, not an artefact
@@ -27,7 +27,7 @@
27
27
  * M-ADR 0134 §4.6 (canonical builder + aggregator).
28
28
  */
29
29
  export const SCHEMA_COMPAT = {
30
- catalogue_schema: "^4.0.0",
30
+ catalogue_schema: "^5.0.0",
31
31
  sdd_manifest: "^1.0.0",
32
32
  aggregation_manifest: "^1.0.0",
33
33
  };
@@ -0,0 +1,77 @@
1
+ // The intent artefact's shape (M-ADR 0227 §4.1), shared by the migration that writes intents and the check
2
+ // that reads them. The section names and header lines are the shipped template's
3
+ // (docs/method/methods/templates/intent-template.md), so a change there is a change here.
4
+ export const INTENT_DIRS = ["content/method/intents", "content/product/intents"];
5
+ export const INTENT_SECTIONS = [
6
+ "Problem",
7
+ "Proposed outcome",
8
+ "Affected users and systems",
9
+ "Constraints",
10
+ "Open questions",
11
+ "Decision to resolve in exploration",
12
+ "ADR requirement",
13
+ "Where it went",
14
+ ];
15
+ /** Header fields of the retired Idea and the idea map: planning state, which belongs in the work item (§4.3). */
16
+ export const PLANNING_FIELDS = [
17
+ "Status",
18
+ "Priority",
19
+ "Blocked by",
20
+ "Enables",
21
+ "Parent Idea",
22
+ "Child Ideas",
23
+ "Idea ID",
24
+ "Epic ID",
25
+ "Theme",
26
+ ];
27
+ /** A "Where it went" line naming a path: "- `<path>` (<sdd-id>; <source>)". */
28
+ export const WHERE_PATH_LINE = /^-\s+`([^`]+)`\s+\(([^;)]+);\s*([^)]+)\)\s*$/;
29
+ /** "## 3. Why Explore This (Revised)" -> "why explore this". */
30
+ export function normaliseHeading(h) {
31
+ return h
32
+ .replace(/^\s*\d+[A-Za-z]?(\.\d+)*\.?\s*/, "")
33
+ .replace(/\((revised|updated)\)\s*$/i, "")
34
+ .trim()
35
+ .toLowerCase();
36
+ }
37
+ export function parseMarkdown(text) {
38
+ const lines = text.split("\n");
39
+ let title = "";
40
+ const fields = new Map();
41
+ const sections = new Map();
42
+ const headings = [];
43
+ let current = null;
44
+ let buf = [];
45
+ const flush = () => {
46
+ if (current !== null) {
47
+ const prev = sections.get(current);
48
+ const body = buf.join("\n").trim();
49
+ sections.set(current, prev ? `${prev}\n\n${body}` : body);
50
+ }
51
+ buf = [];
52
+ };
53
+ for (const line of lines) {
54
+ const h1 = /^#\s+(.+?)\s*$/.exec(line);
55
+ if (h1 && !title && current === null) {
56
+ title = h1[1];
57
+ continue;
58
+ }
59
+ const h2 = /^##\s+(.+?)\s*$/.exec(line);
60
+ if (h2) {
61
+ flush();
62
+ headings.push(h2[1]);
63
+ current = normaliseHeading(h2[1]);
64
+ continue;
65
+ }
66
+ if (current === null) {
67
+ const f = /^\*\*([^*:]+):\*\*\s*(.*?)\s*$/.exec(line);
68
+ if (f)
69
+ fields.set(f[1].trim(), f[2]);
70
+ continue;
71
+ }
72
+ buf.push(line);
73
+ }
74
+ flush();
75
+ return { title, fields, sections, headings };
76
+ }
77
+ //# sourceMappingURL=format.js.map