@synap-core/workspace-templates 0.12.0 → 0.24.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 (237) hide show
  1. package/README.md +509 -0
  2. package/automations/bookmark-enrichment.automation.json +321 -0
  3. package/automations/github-pr-events.automation.json +505 -0
  4. package/automations/mail-feed.automation.json +86 -0
  5. package/automations/ship-a-change-checks-green.automation.json +106 -0
  6. package/automations/ship-a-change-checks-red.automation.json +106 -0
  7. package/automations/ship-a-change-deployed.automation.json +56 -0
  8. package/automations/ship-a-change-pr-merged.automation.json +110 -0
  9. package/automations/ship-a-change-pr-opened.automation.json +104 -0
  10. package/automations/url-bookmark-capture.automation.json +132 -0
  11. package/capabilities/agency-skills.capability.json +157 -0
  12. package/capabilities/apify.capability.json +265 -0
  13. package/capabilities/apollo.capability.json +120 -0
  14. package/capabilities/arch-backend.capability.json +97 -0
  15. package/capabilities/arch-client-intelligence.capability.json +401 -0
  16. package/capabilities/backblaze-b2.capability.json +205 -0
  17. package/capabilities/cal-com.capability.json +266 -0
  18. package/capabilities/canva.capability.json +274 -0
  19. package/capabilities/claude-code-routines.capability.json +172 -0
  20. package/capabilities/claude-managed-agents.capability.json +215 -0
  21. package/capabilities/client-comms-report.capability.json +246 -0
  22. package/capabilities/content-idea-to-production.capability.json +29 -0
  23. package/capabilities/datagouv.capability.json +315 -0
  24. package/capabilities/discord-bot.capability.json +157 -0
  25. package/capabilities/dropbox.capability.json +281 -0
  26. package/capabilities/exa.capability.json +109 -0
  27. package/capabilities/fal-ai.capability.json +83 -0
  28. package/capabilities/fal-media-lab.capability.json +158 -0
  29. package/capabilities/fireflies.capability.json +191 -0
  30. package/capabilities/freellmapi.capability.json +114 -0
  31. package/capabilities/generic-apikey.capability.json +92 -0
  32. package/capabilities/github-merge.capability.json +99 -0
  33. package/capabilities/github-read.capability.json +325 -0
  34. package/capabilities/governance-tighten-recommender.capability.json +81 -0
  35. package/capabilities/jev.capability.json +226 -0
  36. package/capabilities/lead-conversion-enrollment.capability.json +246 -0
  37. package/capabilities/mail-feed.capability.json +277 -0
  38. package/capabilities/mailgun.capability.json +52 -0
  39. package/capabilities/nango-google.capability.json +639 -0
  40. package/capabilities/notion.capability.json +417 -0
  41. package/capabilities/omniroute.capability.json +137 -0
  42. package/capabilities/posthog-analytics.capability.json +258 -0
  43. package/capabilities/postiz.capability.json +467 -0
  44. package/capabilities/proactive-digest.capability.json +190 -0
  45. package/capabilities/proton.capability.json +288 -0
  46. package/capabilities/replicate-rvm.capability.json +97 -0
  47. package/capabilities/research-methods.capability.json +57 -0
  48. package/capabilities/shopify.capability.json +395 -0
  49. package/capabilities/slack.capability.json +369 -0
  50. package/capabilities/stripe.capability.json +1496 -0
  51. package/capabilities/telegram-bridge.capability.json +56 -0
  52. package/capabilities/treg.capability.json +102 -0
  53. package/capabilities/unipile-linkedin.capability.json +494 -0
  54. package/capabilities/vercel.capability.json +424 -0
  55. package/dist/define-DqoItRiR.d.ts +1370 -0
  56. package/dist/index.d.ts +174 -900
  57. package/dist/index.js +26447 -24075
  58. package/dist/index.js.map +1 -1
  59. package/dist/wire.d.ts +222 -0
  60. package/dist/wire.js +77 -0
  61. package/dist/wire.js.map +1 -0
  62. package/package.json +27 -4
  63. package/retired.yaml +136 -0
  64. package/skills/app-factory-build-slice/SKILL.md +70 -0
  65. package/skills/app-factory-build-slice.catalog.json +17 -0
  66. package/skills/app-factory-design-canvas/SKILL.md +96 -0
  67. package/skills/app-factory-design-canvas.catalog.json +17 -0
  68. package/skills/app-factory-design-review/SKILL.md +105 -0
  69. package/skills/app-factory-design-review.catalog.json +18 -0
  70. package/skills/app-factory-research/SKILL.md +123 -0
  71. package/skills/app-factory-research.catalog.json +17 -0
  72. package/skills/bookmark-enrichment/SKILL.md +40 -0
  73. package/skills/carousel-format/carousel-format.skill.json +18 -0
  74. package/skills/collage-broll/collage-broll.skill.json +20 -0
  75. package/skills/content-taste/content-taste.skill.json +18 -0
  76. package/skills/creative-director/creative-director.skill.json +18 -0
  77. package/skills/design-critique/SKILL.md +138 -0
  78. package/skills/design-critique.catalog.json +12 -0
  79. package/skills/designing-with-real-components/SKILL.md +140 -0
  80. package/skills/designing-with-real-components.catalog.json +12 -0
  81. package/skills/edit-loop/edit-loop.skill.json +25 -0
  82. package/skills/facecam-edit/facecam-edit.skill.json +24 -0
  83. package/skills/mapping-the-server/SKILL.md +54 -0
  84. package/skills/math-explainer-manimgx/math-explainer-manimgx.skill.json +20 -0
  85. package/skills/motion-quality-gates/motion-quality-gates.skill.json +20 -0
  86. package/skills/open-design-edit/open-design-edit.skill.json +24 -0
  87. package/skills/reading-client-progress/SKILL.md +65 -0
  88. package/skills/routing-to-channels/SKILL.md +54 -0
  89. package/skills/stellar-scf-grants-advisor/ASSOCIATE-CHEATSHEET.md +133 -0
  90. package/skills/stellar-scf-grants-advisor/ASSOCIATE-ONBOARDING-GUIDE.md +761 -0
  91. package/skills/stellar-scf-grants-advisor/CLIENT-FAQ.md +181 -0
  92. package/skills/stellar-scf-grants-advisor/PARTNER-HANDOVER.md +130 -0
  93. package/skills/stellar-scf-grants-advisor/SKILL.md +102 -0
  94. package/skills/stellar-scf-grants-advisor/examples/README.md +43 -0
  95. package/skills/stellar-scf-grants-advisor/examples/chat-summary-templates.md +158 -0
  96. package/skills/stellar-scf-grants-advisor/examples/corpus-comparable-rows.md +136 -0
  97. package/skills/stellar-scf-grants-advisor/examples/q10-team-rewrites.md +109 -0
  98. package/skills/stellar-scf-grants-advisor/examples/q2-description-rewrites.md +88 -0
  99. package/skills/stellar-scf-grants-advisor/examples/q6-integration-rewrites.md +107 -0
  100. package/skills/stellar-scf-grants-advisor/examples/tranche-structures.md +176 -0
  101. package/skills/stellar-scf-grants-advisor/reference/01-methodology.md +96 -0
  102. package/skills/stellar-scf-grants-advisor/reference/02-scoring-framework.md +199 -0
  103. package/skills/stellar-scf-grants-advisor/reference/03-rejection-patterns.md +241 -0
  104. package/skills/stellar-scf-grants-advisor/reference/04-winner-patterns.md +120 -0
  105. package/skills/stellar-scf-grants-advisor/reference/05-comeback-patterns.md +92 -0
  106. package/skills/stellar-scf-grants-advisor/reference/06-budget-benchmarks.md +125 -0
  107. package/skills/stellar-scf-grants-advisor/reference/07-integration-list.md +147 -0
  108. package/skills/stellar-scf-grants-advisor/reference/08-abstract-fields.md +258 -0
  109. package/skills/stellar-scf-grants-advisor/reference/09-build-fields.md +259 -0
  110. package/skills/stellar-scf-grants-advisor/reference/10-corpus-winners.md +135 -0
  111. package/skills/stellar-scf-grants-advisor/reference/11-corpus-rejects.md +267 -0
  112. package/skills/stellar-scf-grants-advisor/reference/12-client-communication.md +131 -0
  113. package/skills/stellar-scf-grants-advisor/reference/13-excel-output-spec.md +199 -0
  114. package/skills/stellar-scf-grants-advisor/reference/14-worked-examples.md +160 -0
  115. package/skills/stellar-scf-grants-advisor/templates/abstract-review-builder.py +253 -0
  116. package/skills/stellar-scf-grants-advisor/templates/build-review-builder.py +213 -0
  117. package/skills/video-direction/video-direction.skill.json +20 -0
  118. package/skills/video-style-vocabulary/video-style-vocabulary.skill.json +20 -0
  119. package/skills/video-toolbox/video-toolbox.skill.json +20 -0
  120. package/src/__fixtures__/lifecycle-presets.flat-before.json +205 -0
  121. package/src/agency-os.yaml +122 -0
  122. package/src/agent-os-skill-slugs.test.ts +65 -0
  123. package/src/apify-social-reader.test.ts +317 -0
  124. package/src/base.yaml +85 -39
  125. package/src/blockchain-ecosystem.yaml +1 -0
  126. package/src/brand-library.yaml +525 -14
  127. package/src/builder-dev-fold.template.test.ts +113 -0
  128. package/src/builder.yaml +779 -91
  129. package/src/business-model-catalog-description.test.ts +47 -0
  130. package/src/business-model-grp.template.test.ts +214 -0
  131. package/src/business-model.yaml +296 -49
  132. package/src/catalog-safety.test.ts +198 -0
  133. package/src/catalog.template-items.test.ts +75 -0
  134. package/src/catalog.ts +66 -2
  135. package/src/concept-guard.test.ts +28 -8
  136. package/src/concept-guard.ts +2 -2
  137. package/src/content-creation.template.test.ts +52 -0
  138. package/src/content-creation.yaml +192 -0
  139. package/src/content-os.edit-loop.template.test.ts +210 -0
  140. package/src/content-os.publish-due-posts.template.test.ts +261 -0
  141. package/src/content-os.template.test.ts +349 -0
  142. package/src/content-os.video-takes.template.test.ts +338 -0
  143. package/src/content-os.work-a-take.template.test.ts +125 -0
  144. package/src/content-os.yaml +1873 -39
  145. package/src/content-studio-retired.template.test.ts +82 -0
  146. package/src/corpus-flow-validity.test.ts +4 -5
  147. package/src/crm-absorbs-outreach.template.test.ts +117 -0
  148. package/src/crm-build-plan.template.test.ts +128 -0
  149. package/src/crm-lists.template.test.ts +96 -0
  150. package/src/crm-messages-cadence.template.test.ts +246 -0
  151. package/src/crm-one-send-door.template.test.ts +65 -0
  152. package/src/crm.yaml +1563 -181
  153. package/src/decisions-wave.template.test.ts +186 -0
  154. package/src/define.ts +146 -17
  155. package/src/design-to-implementation.template.test.ts +94 -0
  156. package/src/domain-template-type.test.ts +75 -0
  157. package/src/ecosystem.yaml +27 -66
  158. package/src/enterprise-os.yaml +10 -134
  159. package/src/facecam-edit.audio-studio.test.ts +188 -0
  160. package/src/fal-generate-image.test.ts +200 -0
  161. package/src/fal-media-lab-pod-files.test.ts +180 -0
  162. package/src/finance.yaml +254 -1
  163. package/src/foundation.yaml +78 -38
  164. package/src/frame-host-modules.d.mts +6 -0
  165. package/src/frame-host-modules.mjs +58 -0
  166. package/src/generate.mjs +9 -3
  167. package/src/github-merge.test.ts +210 -0
  168. package/src/grants.yaml +46 -17
  169. package/src/hr.yaml +39 -6
  170. package/src/index.ts +36 -1
  171. package/src/intent.test.ts +161 -0
  172. package/src/internal-runbook.yaml +19 -1
  173. package/src/jev.test.ts +356 -0
  174. package/src/legal.yaml +33 -1
  175. package/src/life-os.yaml +51 -240
  176. package/src/lifecycle-coverage.test.ts +124 -0
  177. package/src/lifecycle-declarations.test.ts +252 -0
  178. package/src/lifecycle-presets.test.ts +468 -0
  179. package/src/lifecycle-presets.ts +494 -0
  180. package/src/lifecycle-stuck.test.ts +46 -0
  181. package/src/lifecycle-waits.parity.test.ts +319 -0
  182. package/src/marketing.yaml +108 -4
  183. package/src/meetings-knowledge.yaml +18 -0
  184. package/src/networking.yaml +23 -2
  185. package/src/operations.yaml +304 -4
  186. package/src/pipeline-views.template.test.ts +88 -0
  187. package/src/playbook-goal-placeholders.test.ts +57 -0
  188. package/src/postiz-contract.test.ts +134 -0
  189. package/src/presentation-declarations.test.ts +174 -0
  190. package/src/process-contract.validate.test.ts +352 -0
  191. package/src/project-management.yaml +39 -740
  192. package/src/publish-body.d.mts +29 -0
  193. package/src/publish-body.mjs +74 -0
  194. package/src/publish-body.test.ts +74 -0
  195. package/src/publish-official-lib.test.ts +176 -0
  196. package/src/replicate-rvm.test.ts +504 -0
  197. package/src/research-base.yaml +119 -20
  198. package/src/research-decision.yaml +60 -3
  199. package/src/reserved-profile-slugs.test.ts +81 -0
  200. package/src/retired-goal-kinds.test.ts +52 -0
  201. package/src/role-reference-and-step-domain.test.ts +192 -0
  202. package/src/seed-obligation.test.ts +1 -6
  203. package/src/send-message-maps.test.ts +227 -0
  204. package/src/shared-role-ssot.test.ts +40 -2
  205. package/src/ship-a-change.template.test.ts +177 -0
  206. package/src/skills.test.ts +170 -0
  207. package/src/social.yaml +85 -27
  208. package/src/space-packages.freshness.test.ts +97 -0
  209. package/src/space-packages.generated.ts +40 -0
  210. package/src/space-packages.test.ts +125 -0
  211. package/src/space-packages.ts +73 -0
  212. package/src/start.test.ts +188 -0
  213. package/src/stripe-capability.test.ts +192 -0
  214. package/src/task-intents.test.ts +293 -0
  215. package/src/template-documents.test.ts +158 -0
  216. package/src/templates.ts +20907 -21464
  217. package/src/types.ts +475 -61
  218. package/src/unipile-linkedin-find-profile.test.ts +183 -0
  219. package/src/unipile-publish-post.test.ts +162 -0
  220. package/src/validate-flow.drift.test.ts +2 -3
  221. package/src/validate-flow.ts +22 -2
  222. package/src/validate-onboarding.test.ts +59 -0
  223. package/src/validate.test.ts +71 -4
  224. package/src/validate.ts +1416 -7
  225. package/src/wire-core.ts +231 -0
  226. package/src/wire.test.ts +159 -0
  227. package/src/wire.ts +107 -0
  228. package/views/bookmark-views-pack.view.json +39 -0
  229. package/views/event-views-pack.view.json +45 -0
  230. package/views/task-views-pack.view.json +53 -0
  231. package/src/agent-fleet.yaml +0 -1645
  232. package/src/business-developer.template.test.ts +0 -351
  233. package/src/business-developer.yaml +0 -860
  234. package/src/content-studio.yaml +0 -361
  235. package/src/dev-dashboard.yaml +0 -990
  236. package/src/outreach-comms.yaml +0 -486
  237. package/src/the-arch.yaml +0 -201
package/src/types.ts CHANGED
@@ -1,3 +1,21 @@
1
+ import type { ProfilePresentation } from "@synap-core/types/presentation";
2
+ import type {
3
+ SpaceBrief,
4
+ SpaceBriefAnchor,
5
+ SpaceBriefCollectTarget,
6
+ SpaceBriefExpertise,
7
+ SpaceBriefFetchHint,
8
+ SpaceTemplateRule,
9
+ SpaceTemplateSkill,
10
+ } from "@synap-core/types/space-brief";
11
+
12
+ // The intent vocabulary is imported as a TYPE here (no runtime import), so this
13
+ // file keeps its "zero runtime imports" property that `build.mjs` depends on —
14
+ // it loads `validate.ts` under Node's type-stripper BEFORE `tsup` builds dist/.
15
+ // The RUNTIME membership test lives in `validate.ts`, which is the only place
16
+ // that needs a value.
17
+ import type { CapabilityIntentSlug } from "@synap-core/types/capability-intents";
18
+
1
19
  /**
2
20
  * @synap-core/workspace-templates — Types
3
21
  *
@@ -71,6 +89,14 @@ export type WorkspacePrimarySurface =
71
89
  kind: "url";
72
90
  url: string;
73
91
  title?: string;
92
+ /**
93
+ * The pod app this website is (spec 17 §7.1): its Client ID Metadata
94
+ * Document URL. A launch hint only: the Browser opens the site with the
95
+ * space's pod `iss` so the app starts that pod's OAuth flow. It grants
96
+ * no identity, bridge or credential; the site stays an unprivileged URL.
97
+ * Mirrors the pod's `WorkspacePrimarySurface` (@synap/database).
98
+ */
99
+ podApp?: { clientId: string };
74
100
  }
75
101
  | {
76
102
  kind: "view";
@@ -152,6 +178,79 @@ export interface TemplateProfile {
152
178
  /** For profileKind='role': which base-kind profile slugs this role can attach to. */
153
179
  applicableKinds?: string[];
154
180
  properties: TemplateProperty[];
181
+ /**
182
+ * The kind's / role's ONE lifecycle (work model L1): which select property it
183
+ * is, and a category for each of its options. The pod folds the options onto
184
+ * that property and declares it (`declareLifecycle`); boards, pipelines and
185
+ * governance then read the category, never the option name.
186
+ * `validate.ts` (`lifecycle-*` rules) requires the option keys to be the
187
+ * property's `enumValues`, same order, and every template that declares this
188
+ * profile to declare the same lifecycle.
189
+ *
190
+ * This is the COMPILED shape. The YAML may instead adopt one of the ten base
191
+ * lifecycles (`TemplateLifecycleAdoption`, `lifecycle-presets.ts`) and may
192
+ * omit the select's `enumValues`; `resolveLifecyclePresets` compiles both
193
+ * into this shape before validation, generation and publish.
194
+ */
195
+ lifecycle?: TemplateLifecycle;
196
+ /**
197
+ * How entities of this kind PRESENT themselves (entity rendering, decision
198
+ * 8): the family (media · document · link · record · work), where its media
199
+ * lives, and optional per-altitude fields. Stored on the pod as
200
+ * `uiHints.presentation` and converged on every apply. Parsed by the ONE
201
+ * parser, `parseProfilePresentation` (`@synap-core/types/presentation`);
202
+ * `validate.ts` (`presentation-*` rules) also requires every named property
203
+ * to exist on this profile and every declaration of the slug to agree.
204
+ */
205
+ presentation?: ProfilePresentation;
206
+ }
207
+
208
+ /** Fixed categories (`@synap-core/types/lifecycle` LIFECYCLE_CATEGORIES). */
209
+ export type TemplateLifecycleCategory = "open" | "active" | "paused" | "done" | "lost";
210
+
211
+ export interface TemplateLifecycleOption {
212
+ /** The stored value — one of the property's `enumValues`. */
213
+ key: string;
214
+ label?: string;
215
+ category: TemplateLifecycleCategory;
216
+ /** A `UnitTone` token; absent ⇒ the category's default tone. */
217
+ tone?: string;
218
+ /** Only a person may move a thing INTO this option. */
219
+ humanOnly?: boolean;
220
+ /**
221
+ * Days a thing may sit in this option before it is STUCK (an intent
222
+ * surface's Stuck count). Whole days, 1–3650; open/active/paused only.
223
+ */
224
+ stuckAfterDays?: number;
225
+ /**
226
+ * The date property this step is bound to (an invoice's `dueDate` while
227
+ * `sent`): the thing is LATE once that date passes while it stands here.
228
+ * A property slug; open/active/paused only.
229
+ */
230
+ dateBinding?: string;
231
+ /**
232
+ * The wait this step declares: an ACTIVE step such as "sent" waits on
233
+ * someone without being a pause. Open/active/paused only.
234
+ */
235
+ waits?: TemplateLifecycleOptionWaits;
236
+ }
237
+
238
+ /** A step's declared wait (the pod's `LifecycleOptionWaits`). */
239
+ export interface TemplateLifecycleOptionWaits {
240
+ /** A hold's `on`, never `unspecified`: person · agent · external · thing · decision · date · nobody. */
241
+ on: "person" | "agent" | "external" | "thing" | "decision" | "date" | "nobody";
242
+ /** The finer kind (`WAIT_KINDS`: "signature", "payment"…); absent ⇒ derived from `on`. */
243
+ waitKind?: string;
244
+ /** The property or relation naming WHO or WHAT is waited on (a deal's `contactId`). */
245
+ refFrom?: string;
246
+ /** The date property that ends the wait (a lead's `nextActionAt`). */
247
+ dateBinding?: string;
248
+ }
249
+
250
+ export interface TemplateLifecycle {
251
+ /** The lifecycle property's slug (a select of this profile). */
252
+ property: string;
253
+ options: TemplateLifecycleOption[];
155
254
  }
156
255
 
157
256
  export interface TemplateView {
@@ -167,11 +266,41 @@ export interface TemplateView {
167
266
  groupBy?: string;
168
267
  }
169
268
 
269
+ /**
270
+ * A document a template carries. Mirrors `WorkspaceDocumentInput`
271
+ * (synap-backend `@synap-core/types/workspaces/definition`) VERBATIM; the pod
272
+ * installs it through `utils/template-documents.ts` (the one create door,
273
+ * system-authored, owned by the installer, identified in the space by `slug`).
274
+ */
275
+ export interface TemplateDocument {
276
+ /** Stable id inside the template, kebab-case. Never rename it: the space knows the document by it. */
277
+ slug: string;
278
+ /** The document's name (its one title). */
279
+ title: string;
280
+ /** Markdown body; may carry `synap-cell` / `synap-section` embeds. */
281
+ content: string;
282
+ /**
283
+ * What its embeds read (a living document's scope): `space` = the space it
284
+ * is installed in, `pod` = the whole pod. Absent = no scope.
285
+ */
286
+ scope?: "space" | "pod";
287
+ }
288
+
170
289
  export interface TemplateEntityLink {
171
290
  sourceProfileSlug: string;
172
291
  targetProfileSlug: string;
173
292
  type: string;
174
293
  label?: string;
294
+ /**
295
+ * Every record of the source kind should carry this link (an edge of `type`
296
+ * to the target kind). Several rows of one source kind and one `type` are ONE
297
+ * rule, met by an edge to any of their targets. The pod's template reconcile
298
+ * stores it on `profile_relations.metadata` (`required`, `requiredBy`); its
299
+ * create doors warn when a new record leaves it out (never refuse yet) and
300
+ * template health lists the records missing it. Omitted = says nothing (a
301
+ * mark another template set stays); `false` clears the mark.
302
+ */
303
+ required?: boolean;
175
304
  }
176
305
 
177
306
  /**
@@ -249,10 +378,12 @@ export interface TemplateSidebarSurface {
249
378
  }
250
379
 
251
380
  export interface TemplateSidebarItem {
252
- kind: "app" | "view" | "profile" | "external" | "cell";
381
+ kind: "app" | "view" | "profile" | "external" | "cell" | "document";
253
382
  appId?: string;
254
383
  viewName?: string;
255
384
  viewId?: string;
385
+ /** kind "document": the `documents[].slug` it opens (the pod stores its id beside it). */
386
+ documentSlug?: string;
256
387
  profileSlug?: string;
257
388
  url?: string;
258
389
  cellKey?: string;
@@ -320,65 +451,40 @@ export interface TemplateDefaultSource {
320
451
  }
321
452
 
322
453
  // ============================================================================
323
- // Onboarding spec — the per-workspace dynamic onboarding CONTEXT
454
+ // The space brief — `onboarding:` in a template, stored at
455
+ // workspace.settings.onboarding.
324
456
  //
325
- // Written to workspace.settings.onboarding. The SHARED `onboard` skill (the
326
- // reusable adaptive interview PROCESS) reads this to know WHAT a given
327
- // workspace needs — without a per-domain skill file. The domain knowledge
328
- // lives here as data, declared by each template. Mirrors `OnboardingSpec` in
329
- // synap-backend `package-definition.ts` so the wire shape never drifts.
457
+ // ONE type: `SpaceBrief` in `@synap-core/types/space-brief` (type-only import;
458
+ // tsup inlines it into this package's .d.ts, so there is no runtime
459
+ // dependency). The interview fields (goal / collect / openingQuestions /
460
+ // doneWhen) are the brief's ONBOARDING MODE, read by the shared `onboard`
461
+ // skill; purpose / anchors / fetch are its steady state, read by every agent
462
+ // that enters the space. The names below are aliases, not declarations.
330
463
  // ============================================================================
331
464
 
332
- export interface TemplateOnboardingCollectTarget {
333
- /** Profile slug to populate (e.g. "audience", "competitor"). */
334
- profileSlug: string;
335
- /** Human description of what to capture for this target. */
336
- what: string;
337
- /** Roughly how many to expect — guides interview depth. */
338
- cardinality?: "one" | "few" | "several";
339
- /** Key fields the agent should make sure to fill. */
340
- keyFields?: string[];
341
- }
342
-
343
- // Authored domain expertise the onboarding agent LEADS with — so it resolves
344
- // the founder's gaps (brings best practices they lack, surfaces what they miss)
345
- // instead of only extracting what they already know. Consumed by the `onboard`
346
- // skill; see its "Lead with your expertise" step.
347
- export interface TemplateOnboardingExpertise {
348
- /**
349
- * Concrete starting points the agent PROPOSES instead of asking blank —
350
- * "most X do Y, want that as a starting point?". Grounds the agent's
351
- * proposals in real domain knowledge (never fabricates strategy — for
352
- * mission/positioning these FRAME, they don't invent the answer).
353
- */
354
- starters?: string[];
355
- /**
356
- * Blind spots founders in this domain commonly miss. The agent proactively
357
- * surfaces these if the founder hasn't — catching what they don't say.
358
- */
359
- blindSpots?: string[];
360
- /** What a GREAT result looks like here — the bar the agent pushes toward. */
361
- bar?: string;
362
- }
363
-
364
- export interface TemplateOnboarding {
365
- /** The outcome this onboarding achieves, in one sentence. */
366
- goal: string;
367
- /** Domain framing/voice the agent adopts for THIS workspace (the persona). */
368
- framing: string;
369
- /**
370
- * Authored domain expertise the agent leads with (optional). Turns the
371
- * interview from "extract what the founder knows" into "resolve what they
372
- * lack". See the `onboard` skill's "Lead with your expertise" step.
373
- */
374
- expertise?: TemplateOnboardingExpertise;
375
- /** What structured data to collect (entities to create + their key fields). */
376
- collect: TemplateOnboardingCollectTarget[];
377
- /** A few opening questions — the agent adapts from here, never rigid. */
378
- openingQuestions?: string[];
379
- /** "Done" signal the agent self-evaluates against. */
380
- doneWhen?: string;
381
- }
465
+ export type TemplateOnboardingCollectTarget = SpaceBriefCollectTarget;
466
+ export type TemplateOnboardingExpertise = SpaceBriefExpertise;
467
+ export type TemplateBriefAnchor = SpaceBriefAnchor;
468
+ export type TemplateBriefFetchHint = SpaceBriefFetchHint;
469
+ /**
470
+ * A template's brief. `rules` is NOT authored here — a template declares its
471
+ * rules at the top level (`rules:`); the pod stores only refs to them.
472
+ */
473
+ export type TemplateOnboarding = Omit<SpaceBrief, "rules">;
474
+ /**
475
+ * A rule a template installs in its space — applied through the pod's ONE rule
476
+ * door, stamped so a later template update never overwrites a rule the user
477
+ * edited. `key` is its stable identity across template versions.
478
+ */
479
+ export type TemplateRule = SpaceTemplateRule;
480
+ /**
481
+ * A SKILL a template declares for its space (`skills:`). Same shape as a rule —
482
+ * the template declares, the pod LINKS the skill to the space at install and
483
+ * keeps a ref in the brief. `mode: "always"` is prepended to every session or
484
+ * run started in the space; `on-demand` is surfaced and ranked first instead.
485
+ * Validation (`validateSpaceSkillDeclaration`) is shared with the pod's applier.
486
+ */
487
+ export type TemplateSkill = SpaceTemplateSkill;
382
488
 
383
489
  // ============================================================================
384
490
  // Playbooks — session templates seeded with the workspace
@@ -402,7 +508,23 @@ export interface TemplatePlaybook {
402
508
  goalTemplate: string;
403
509
  params?: TemplatePlaybookParam[];
404
510
  executor?: "is-agent" | "external-agent" | "hybrid";
405
- inputStrategy?: "none" | "static" | "rotating" | "query";
511
+ /**
512
+ * Legacy fan-out modes stay strings. `pinned` is an object: first eligible
513
+ * pin, then `fallback`. Entity ids are not part of this shape.
514
+ */
515
+ inputStrategy?:
516
+ | "none"
517
+ | "static"
518
+ | "rotating"
519
+ | "query"
520
+ | {
521
+ kind: "pinned";
522
+ fallback?: {
523
+ filter?: Record<string, unknown>;
524
+ orderBy?: string;
525
+ orderDir?: "asc" | "desc";
526
+ };
527
+ };
406
528
  channelSpec?: {
407
529
  type: "GROUP" | "AGENT_COLLAB" | "THREAD";
408
530
  members?: string[];
@@ -423,16 +545,183 @@ export interface TemplatePlaybook {
423
545
  * governance marker for unattended maintenance playbooks:
424
546
  * `{ governance: { forceProposeWrites: true } }` — every agent write in the
425
547
  * playbook's scheduled sessions then routes to a reviewable proposal.
548
+ * `lineage` is a CONVENTION (no reader enforces it): where the process comes
549
+ * from (an APQC PCF id, a named method, O*NET task ids).
426
550
  */
427
- metadata?: Record<string, unknown>;
551
+ metadata?: Record<string, unknown> & { lineage?: TemplatePlaybookLineage };
428
552
  /**
429
553
  * The entity kind this playbook operates over, persisted to
430
554
  * `playbooks.subject_profile`. Makes the playbook matchable by
431
555
  * `playbooks.matchForEntity` (filters `subject_profile->>'profileSlug'`), so a
432
556
  * captured entity of this kind can auto-launch the playbook as a session.
557
+ *
558
+ * `statusProperty` names the subject kind's SELECT property that holds its
559
+ * lifecycle (e.g. `post-status`). It is what ties `stages[].subjectStatus`
560
+ * to the subject: advancing into a stage writes that value (governed), and
561
+ * the subject entering the value advances an open run to the stage.
562
+ * `validate.ts` checks it is a select property of the kind, and that every
563
+ * `subjectStatus` / activator `status` is one of its enum values.
433
564
  */
434
- subjectProfile?: { profileSlug: string; filter?: Record<string, unknown> };
565
+ subjectProfile?: {
566
+ profileSlug: string;
567
+ /**
568
+ * Narrows a kind-bound SCHEDULE's fan-out: a JSON string of
569
+ * `{ "properties.<key>": value }`. A STRING, because the pod's cron door
570
+ * keeps only a string (`readSubjectProfile`, synap-backend
571
+ * cron-automation.ts) — an object would be dropped, and an unfiltered AI
572
+ * fan-out is refused, so the schedule would silently never be created.
573
+ */
574
+ filter?: string;
575
+ statusProperty?: string;
576
+ };
577
+ /**
578
+ * Playbook-level slots: what a run of this process is expected to produce.
579
+ * Instantiated as the session's owed slots (`sanitizeDeclaredOutputs`).
580
+ */
581
+ expectedOutputs?: TemplateExpectedOutput[];
582
+ /** Binary acceptance criteria every run is graded against (pod `sessionCriteriaSchema`). */
583
+ criteria?: TemplateCriterion[];
584
+ /**
585
+ * The abstract intents the process needs the pod to be able to do — the
586
+ * closed `capability_intents` vocabulary (`@synap-core/types/capability-intents`).
587
+ */
588
+ requiredIntents?: string[];
589
+ /**
590
+ * DECLARATIONS of when the process starts. Compiled at install/apply into
591
+ * governed rules through the pod's ONE rule door and linked in
592
+ * `playbook_automations` (role `activator`) — never hand-written template
593
+ * `automations:`. Public templates default to `mode: propose`.
594
+ */
595
+ activators?: TemplatePlaybookActivator[];
596
+ /**
597
+ * TEMPLATE-AUTHORING ONLY. Values of `subjectProfile.statusProperty` that no
598
+ * stage owns because a PERSON sets them (e.g. Idea, Archived). The lifecycle
599
+ * coverage ratchet (`lifecycle-coverage.test.ts`) requires every enum value
600
+ * of the status property to be either a stage's `subjectStatus` or listed
601
+ * here, so a lifecycle state can never be silently orphaned by a process.
602
+ */
603
+ humanOnlyStatuses?: string[];
435
604
  status?: "draft" | "active" | "paused";
605
+ /**
606
+ * `project` = a TRACK template (a method a project runs over its `stages`);
607
+ * `session` / omitted = a work template. The kind is DERIVED from this, never
608
+ * declared elsewhere (concepts.md).
609
+ */
610
+ scope?: "session" | "project";
611
+ /** Ordered steps. Validated at the pod door by `playbookStageSchema`. */
612
+ stages?: TemplatePlaybookStage[];
613
+ }
614
+
615
+ /**
616
+ * One step of a playbook. Mirrors the pod's `PlaybookStage` (@synap/playbooks)
617
+ * for the fields templates author; the pod schema stays the authority.
618
+ */
619
+ export interface TemplatePlaybookStage {
620
+ key: string;
621
+ name: string;
622
+ category: "backlog" | "planned" | "started" | "paused" | "completed" | "canceled";
623
+ description?: string;
624
+ goal?: string;
625
+ suggestedTasks?: string[];
626
+ indefinite?: boolean;
627
+ /**
628
+ * The DOMAIN the step is worked in: a workspace TEMPLATE slug that becomes a
629
+ * workspace's `package_slug` (e.g. `foundation`, `finance`) — never an
630
+ * overlay's slug (an overlay never owns a workspace), a workspace id or a
631
+ * display name. `validate.ts` rule `stage-domain-*` enforces it.
632
+ */
633
+ domain?: string;
634
+ expectedOutputs?: TemplateExpectedOutput[];
635
+ /** Binary acceptance criteria of THIS stage (a `check` gate evaluates them). */
636
+ criteria?: TemplateCriterion[];
637
+ /**
638
+ * Entry gate. `human` files a review; `check` evaluates the criteria of the
639
+ * stage being LEFT before the run may continue (pod `stage-gate.ts`).
640
+ */
641
+ gate?: { kind: "human" | "check"; proposalType?: "playbook.stage_gate" };
642
+ /**
643
+ * The value of the playbook's `subjectProfile.statusProperty` this stage
644
+ * corresponds to. Advancing INTO the stage writes it to the subject
645
+ * (governed); the subject ENTERING it advances an open run to the stage.
646
+ */
647
+ subjectStatus?: string;
648
+ /** Where a rejected human gate / failed check sends the run back (a stage key or name). */
649
+ onFail?: { toStage: string };
650
+ [key: string]: unknown;
651
+ }
652
+
653
+ /**
654
+ * One declared output slot (playbook- or stage-level). Mirrors the pod's
655
+ * `ExpectedOutput` (@synap/playbooks) for the fields templates author.
656
+ */
657
+ export interface TemplateExpectedOutput {
658
+ /** The output's kind — a profile slug for entities. */
659
+ kind: string;
660
+ label: string;
661
+ icon?: string;
662
+ owner?: "human" | "agent";
663
+ key?: string;
664
+ /**
665
+ * Relation type written output → subject when the slot is satisfied (e.g.
666
+ * `made_for`, `derived_from`). Must resolve to a relation the corpus defines
667
+ * (`entityLinks[].type` / `relationDefs[].slug`). `none` = deliberately no
668
+ * edge (a playbook with no subject, whose outputs stand alone).
669
+ */
670
+ relationToSubject?: string;
671
+ /**
672
+ * `true` = nobody owes this slot (synap-backend 30a9ab85): no needs-you row,
673
+ * never an unmet outcome at a gate or at completion; filled, it counts like
674
+ * any slot. Absent = required. Read STRICTLY — only a boolean `true`
675
+ * (validate.ts `output-optional-not-boolean`). A BIRTH declaration: a change
676
+ * reaches new runs and new stage entries only.
677
+ */
678
+ optional?: boolean;
679
+ [key: string]: unknown;
680
+ }
681
+
682
+ /** A binary acceptance criterion — mirrors the pod's strict `sessionCriterionSchema`. */
683
+ export interface TemplateCriterion {
684
+ /** Lowercase slug, unique within the list. */
685
+ key: string;
686
+ statement: string;
687
+ required?: boolean;
688
+ check: {
689
+ kind: "evidence" | "capability" | "judge" | "human";
690
+ capability?: string;
691
+ evidenceKey?: string;
692
+ hint?: string;
693
+ };
694
+ stageKey?: string;
695
+ }
696
+
697
+ /** A declared process activator (compiled to a governed rule at install). */
698
+ export interface TemplatePlaybookActivator {
699
+ /**
700
+ * `created` / `enters_status` per thing; `count` (≥ `min` things in
701
+ * `status`) and `schedule` (on `cron`) over the whole set; `manual` a
702
+ * button that compiles no rule. The pod's grammar (`ACTIVATOR_ON`).
703
+ */
704
+ on: "created" | "enters_status" | "count" | "schedule" | "manual";
705
+ /** Required for `enters_status` / `count`, optional for `schedule`: a value of the status property. */
706
+ status?: string;
707
+ /** Required for `schedule` (UTC). */
708
+ cron?: string;
709
+ /** Required for `count`. */
710
+ min?: number;
711
+ /** `per_thing` (default) or `per_moment`; count/schedule are per_moment. */
712
+ size?: "per_thing" | "per_moment";
713
+ mode: "run" | "propose";
714
+ /** Pending approvals before the worker stops starting runs (default 20). */
715
+ maxPendingApprovals?: number;
716
+ /** Per-thing `created` / `enters_status` only: leave out a thing that carries this property. */
717
+ unless?: { property: string; present: true };
718
+ }
719
+
720
+ /** Where a process comes from — convention only, read by nobody yet. */
721
+ export interface TemplatePlaybookLineage {
722
+ apqc?: string;
723
+ method?: string;
724
+ onet?: string[];
436
725
  }
437
726
 
438
727
  // ============================================================================
@@ -612,7 +901,7 @@ export interface TemplateExtendsRef {
612
901
  * in repos this package does not own, so they must match this list EXACTLY:
613
902
  *
614
903
  * - marketplace `features/marketplace/src/types.ts`
615
- * - onboarding `features/onboarding/src/{templates/workspace-templates,components/WorkspacePreview}.ts(x)`
904
+ * - onboarding `features/onboarding/src/templates/workspace-templates.ts`
616
905
  * - browser `InstallPackageDialog.tsx`
617
906
  * - synap-backend `package-definition.ts` (`PackageDependencyKind`)
618
907
  * - hub-protocol REST `rest/packages.ts` (zod enum)
@@ -697,12 +986,80 @@ export interface TemplateMeta {
697
986
  * or missing value is grouped, never dropped — see `./domains.ts`.
698
987
  */
699
988
  domain?: string;
989
+ /**
990
+ * WHAT THE SPACE PRODUCES — the purpose word shown first ("Product · Dev")
991
+ * and the kinds/roles it makes, in order. An empty `produces` (or none) makes
992
+ * the space a LIBRARY. Every produced profile is the template's own or one
993
+ * it depends on, and declares a lifecycle (`validate.ts` `intent-*` rules).
994
+ * Forwarded to the pod (top-level `intent` on both doors), which projects it into
995
+ * `workspaces.settings.intent`.
996
+ */
997
+ intent?: TemplateIntent;
998
+ /**
999
+ * An ONBOARDING START: this space offers itself as a first thing to run
1000
+ * ("What should Synap run first?"). Declared once here, read by the pod, the
1001
+ * CP and the landing. Rules: `validate.ts` `start-*`. Forwarded as top-level
1002
+ * `start` on the package door, never in `_meta`.
1003
+ */
1004
+ start?: TemplateStart;
1005
+ }
1006
+
1007
+ /** `meta.start.label` reuses {@link INTENT_LABEL_MAX}; these bound the lists. */
1008
+ export const START_VIEWS_MAX = 3;
1009
+ export const START_EXAMPLE_RANGE = [4, 6] as const;
1010
+ export const START_STARTERS_RANGE = [3, 6] as const;
1011
+
1012
+ /** `meta.start` — see {@link TemplateMeta.start}. */
1013
+ export interface TemplateStart {
1014
+ /** Card order; unique across the catalog's starts. */
1015
+ order: number;
1016
+ /** ≤ {@link INTENT_LABEL_MAX} chars. */
1017
+ label: string;
1018
+ promise: string;
1019
+ /** Identity ids this start is suggested for; each id belongs to one start. */
1020
+ suggestFor: string[];
1021
+ /** The produced kind the views and the first session are about. */
1022
+ profile: string;
1023
+ /** 1-3 slugs of THIS template's views, scoped to `profile`; first = default. */
1024
+ views: string[];
1025
+ /** Preview rows, never written. `values` keys are properties of `profile`. */
1026
+ example: Array<{ title: string; values?: Record<string, unknown> }>;
1027
+ firstSession: { title: string; goal: string };
1028
+ /** "Build it with me" chips. */
1029
+ starters: string[];
1030
+ }
1031
+
1032
+ /** `meta.intent.label` max — the purpose word must fit before " · <name>". */
1033
+ export const INTENT_LABEL_MAX = 24;
1034
+
1035
+ /** `meta.intent` — see {@link TemplateMeta.intent}. */
1036
+ export interface TemplateIntent {
1037
+ /** ≤ {@link INTENT_LABEL_MAX} chars. */
1038
+ label: string;
1039
+ produces?: Array<{ profile: string }>;
700
1040
  }
701
1041
 
702
1042
  export interface WorkspaceYaml {
703
1043
  /** Template metadata — not sent to backend, used for listing/UI */
704
1044
  meta: TemplateMeta;
705
1045
 
1046
+ /**
1047
+ * THE WORKSPACE'S TASK REQUIREMENTS — the specific intents (closed
1048
+ * vocabulary, `@synap-core/types/capability-intents`) this workspace needs to
1049
+ * function. The SSOT for WHAT THE SPACE REQUIRES, as distinct from
1050
+ * `workspace.capabilities`, which names what it PROVIDES to others.
1051
+ *
1052
+ * Every value is validated against the closed vocabulary by
1053
+ * `validateTemplate` (`task-intent-unknown`), so a typo fails at authoring
1054
+ * time rather than installing a capability axis nobody can route.
1055
+ *
1056
+ * Deliberately NOT forwarded by either converter yet: the backend has no
1057
+ * `taskIntents` sink on `createFromDefinition` (see `WorkspaceDefinitionDropped`
1058
+ * in `define.ts`, which records that). Phase 1 is the declaration + its
1059
+ * guard; wiring it to a sink is a follow-up that must edit that ledger.
1060
+ */
1061
+ taskIntents?: CapabilityIntentSlug[];
1062
+
706
1063
  /** The workspace definition sent to createFromDefinition */
707
1064
  workspace: {
708
1065
  name: string;
@@ -740,6 +1097,15 @@ export interface WorkspaceYaml {
740
1097
  /** Curated views — only the ones that add value */
741
1098
  views?: TemplateView[];
742
1099
 
1100
+ /**
1101
+ * Documents the space carries (plan 9ad4b2fc §5 lane 12, P4: a pinned set of
1102
+ * documents hosts a space package). Installed by the pod with the views:
1103
+ * created once per `slug` in the space, never rewritten by an update. A
1104
+ * sidebar item `{kind: "document", documentSlug}` opens one. See
1105
+ * {@link TemplateDocument}.
1106
+ */
1107
+ documents?: TemplateDocument[];
1108
+
743
1109
  /** Schema-level links between entity types */
744
1110
  entityLinks?: TemplateEntityLink[];
745
1111
 
@@ -807,6 +1173,27 @@ export interface WorkspaceYaml {
807
1173
  */
808
1174
  onboarding?: TemplateOnboarding;
809
1175
 
1176
+ /**
1177
+ * Rules this template installs in its space (package `rules[]`). See
1178
+ * {@link TemplateRule}.
1179
+ */
1180
+ rules?: TemplateRule[];
1181
+
1182
+ /**
1183
+ * Skills this template declares for its space (package `skills[]`). The pod
1184
+ * links each to the new space at install, approved skills only, so every AI
1185
+ * working there is told them. See {@link TemplateSkill}.
1186
+ */
1187
+ skills?: TemplateSkill[];
1188
+
1189
+ /**
1190
+ * The space's own experience as CODE: the modules this template builds into
1191
+ * sandboxed frame cells and installs in its space (package `cells[]`, typeKey
1192
+ * `cell:<meta.slug>:<key>`). The template's `app: {kind: stored, cellKey}`
1193
+ * opens one of them. See {@link TemplateSpacePackage}.
1194
+ */
1195
+ spacePackage?: TemplateSpacePackage;
1196
+
810
1197
  /** Inherit profiles/views from other workspaces */
811
1198
  extends?: TemplateExtendsRef[];
812
1199
 
@@ -819,6 +1206,33 @@ export interface WorkspaceYaml {
819
1206
  dependencies?: TemplateDependency[];
820
1207
  }
821
1208
 
1209
+ // ============================================================================
1210
+ // Space package — the space's experience as built code
1211
+ // ============================================================================
1212
+
1213
+ /**
1214
+ * One module of a space package. `source` is the entry file, relative to the
1215
+ * synap-app repo root and under `packages/web/src/space-packages/`, so the
1216
+ * package is built from the SAME shared components every surface uses, never
1217
+ * from a copy. `scripts/build-space-packages.mjs` bundles it (React external,
1218
+ * host-inlined in the frame; its CSS injected by the module) into
1219
+ * `src/space-packages.generated.ts`, and `toPackageDefinition` carries it as a
1220
+ * `frame` cell.
1221
+ */
1222
+ export interface TemplateSpacePackageCell {
1223
+ /** Cell key inside the package: the installed typeKey is `cell:<meta.slug>:<key>`. */
1224
+ key: string;
1225
+ /** Display name of the installed cell. */
1226
+ name: string;
1227
+ /** Entry module, repo-relative (`packages/web/src/space-packages/<pkg>/<file>.tsx`). */
1228
+ source: string;
1229
+ }
1230
+
1231
+ /** The space package a template installs (base layer; the person's overlay comes later). */
1232
+ export interface TemplateSpacePackage {
1233
+ cells: TemplateSpacePackageCell[];
1234
+ }
1235
+
822
1236
  // ============================================================================
823
1237
  // Resolved template — meta + fully typed definition ready for provisioning
824
1238
  // ============================================================================