@synap-core/workspace-templates 0.29.0 → 0.31.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.
Files changed (44) hide show
  1. package/README.md +12 -4
  2. package/dist/{define-DqoItRiR.d.ts → define-DHDi8C33.d.ts} +19 -18
  3. package/dist/index.d.ts +2 -2
  4. package/dist/index.js +594 -241
  5. package/dist/index.js.map +1 -1
  6. package/dist/wire.d.ts +1 -1
  7. package/package.json +1 -1
  8. package/src/brand-library.yaml +0 -6
  9. package/src/builder-dev-fold.template.test.ts +2 -3
  10. package/src/builder-dev-playbooks.template.test.ts +7 -5
  11. package/src/builder.yaml +162 -32
  12. package/src/business-model.yaml +20 -1
  13. package/src/civic-france.yaml +9 -0
  14. package/src/content-creation.yaml +1 -1
  15. package/src/content-os.yaml +22 -18
  16. package/src/crm-absorbs-outreach.template.test.ts +1 -1
  17. package/src/crm-build-plan.template.test.ts +1 -1
  18. package/src/crm.yaml +5 -14
  19. package/src/decisions-wave.template.test.ts +7 -5
  20. package/src/define.primary-surface.test.ts +9 -0
  21. package/src/define.ts +4 -1
  22. package/src/finance.yaml +10 -6
  23. package/src/foundation.yaml +1 -2
  24. package/src/hr.yaml +3 -2
  25. package/src/intent.test.ts +44 -3
  26. package/src/internal-runbook.yaml +0 -1
  27. package/src/kanban-grouping.test.ts +72 -0
  28. package/src/legal.yaml +4 -4
  29. package/src/lifecycle-coverage.test.ts +7 -64
  30. package/src/lifecycle-declarations.test.ts +70 -74
  31. package/src/marketing.yaml +4 -3
  32. package/src/meetings-knowledge.yaml +1 -2
  33. package/src/operations.yaml +13 -9
  34. package/src/process-contract.validate.test.ts +40 -55
  35. package/src/project-management.yaml +2 -2
  36. package/src/publish-official-lib.test.ts +3 -2
  37. package/src/research-base.yaml +22 -15
  38. package/src/research-decision.yaml +18 -2
  39. package/src/ship-a-change.template.test.ts +3 -2
  40. package/src/social.yaml +4 -1
  41. package/src/start.test.ts +22 -0
  42. package/src/templates.ts +490 -185
  43. package/src/types.ts +28 -18
  44. package/src/validate.ts +143 -77
@@ -45,6 +45,15 @@ profiles:
45
45
  # Pod-wide `question` is a first-class KIND (Decision 1 — the manifest retired
46
46
  # w4.convert.question to a keep no-op). Declared as a plain kind to match the
47
47
  # seed + research-base and reuse the existing pod-wide row.
48
+ # The pod seeds this lifecycle on every pod (ensure-system-lifecycles.ts);
49
+ # declared here to match the seed exactly, so a playbook can follow it.
50
+ lifecycle:
51
+ property: questionStatus
52
+ options:
53
+ - { key: open, category: open }
54
+ - { key: exploring, category: active }
55
+ - { key: answered, category: done }
56
+ - { key: abandoned, category: lost }
48
57
  properties:
49
58
  - slug: questionStatus
50
59
  label: Status
@@ -83,6 +92,15 @@ profiles:
83
92
  # Pod-wide `decision` is a first-class KIND (Decision 1 — w4.convert.decision
84
93
  # retired to a keep no-op). Declared as a plain kind to match the seed; the
85
94
  # `resolves` / `considered_in` links resolve against the reused pod-wide row.
95
+ # The pod seeds this lifecycle on every pod (ensure-system-lifecycles.ts);
96
+ # declared here to match the seed exactly, so a playbook can follow it.
97
+ lifecycle:
98
+ property: decisionStatus
99
+ options:
100
+ - { key: proposed, category: open }
101
+ - { key: accepted, category: done }
102
+ - { key: superseded, category: lost }
103
+ - { key: rejected, category: lost }
86
104
  properties:
87
105
  - slug: summary
88
106
  label: Summary
@@ -168,8 +186,6 @@ playbooks:
168
186
  superseded.
169
187
  subjectProfile:
170
188
  profileSlug: decision
171
- statusProperty: decisionStatus
172
- humanOnlyStatuses: [superseded, rejected]
173
189
  activators:
174
190
  - { on: created, mode: propose }
175
191
  params:
@@ -67,8 +67,9 @@ const outputs = (type: string) =>
67
67
  );
68
68
 
69
69
  describe("Ship a change — the process follows the feature's lifecycle", () => {
70
- it("names the lifecycle property, and every status it writes or reads is an option of it", () => {
71
- expect(pb.subjectProfile.statusProperty).toBe(feature.lifecycle.property);
70
+ it("follows the feature's lifecycle (names no statusProperty), and every status it writes or reads is an option of it", () => {
71
+ expect(pb.subjectProfile.statusProperty).toBeUndefined();
72
+ expect(pb.subjectProfile.profileSlug).toBe("devplane_feature");
72
73
  const options = new Set(feature.lifecycle.options.map((o) => o.key));
73
74
  const used = [
74
75
  ...pb.stages.map((s) => s.subjectStatus).filter(Boolean),
package/src/social.yaml CHANGED
@@ -16,6 +16,8 @@ meta:
16
16
  # What this space PRODUCES (homes): the purpose word, then its kinds/roles.
17
17
  intent:
18
18
  label: Distribution
19
+ # The ONE primary output (One model decision 3): a published post, its one produced kind.
20
+ primary: post
19
21
  produces:
20
22
  - profile: post
21
23
 
@@ -297,7 +299,8 @@ views:
297
299
  slug: content-calendar
298
300
  type: kanban
299
301
  scopeProfileSlug: post
300
- groupBy: post-status
302
+ config:
303
+ groupByField: post-status
301
304
  description: "Posts on a board by status — idea to published."
302
305
  - name: Platforms
303
306
  slug: platforms
package/src/start.test.ts CHANGED
@@ -130,6 +130,28 @@ describe("meta.start — validator rules", () => {
130
130
  });
131
131
  });
132
132
 
133
+ describe("meta.start — the kind defaults to the primary output (one source)", () => {
134
+ const withPrimary = (start: Partial<TemplateStart>) => {
135
+ const t = make("t", start);
136
+ t.meta.intent = { label: "Sales", primary: "deal", produces: [{ profile: "deal" }] };
137
+ return t;
138
+ };
139
+ // Negative control: goes red with the start-profile-* block removed from checkStart.
140
+ it("an omitted profile reads meta.intent.primary, and the wire carries it", () => {
141
+ const t = withPrimary({ profile: undefined });
142
+ expect(startErrors(t)).toEqual([]);
143
+ expect(toPackageDefinition(t).start?.profile).toBe("deal");
144
+ });
145
+
146
+ it("start-profile-redundant: naming the primary again is a second copy", () => {
147
+ expect(startErrors(withPrimary({ profile: "deal" }))).toEqual(["start-profile-redundant"]);
148
+ });
149
+
150
+ it("start-profile-missing: no profile and no primary to default to", () => {
151
+ expect(startErrors(make("t", { profile: undefined }))).toEqual(["start-profile-missing"]);
152
+ });
153
+ });
154
+
133
155
  describe("meta.start — package door", () => {
134
156
  it("carries a top-level start, never in _meta", () => {
135
157
  const def = toPackageDefinition(make("t"));