@synap-core/workspace-templates 0.12.0 → 0.23.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.
- package/README.md +483 -0
- package/automations/bookmark-enrichment.automation.json +321 -0
- package/automations/github-pr-events.automation.json +505 -0
- package/automations/mail-feed.automation.json +86 -0
- package/automations/ship-a-change-checks-green.automation.json +106 -0
- package/automations/ship-a-change-checks-red.automation.json +106 -0
- package/automations/ship-a-change-deployed.automation.json +56 -0
- package/automations/ship-a-change-pr-merged.automation.json +110 -0
- package/automations/ship-a-change-pr-opened.automation.json +104 -0
- package/automations/url-bookmark-capture.automation.json +132 -0
- package/capabilities/agency-skills.capability.json +157 -0
- package/capabilities/apify.capability.json +265 -0
- package/capabilities/apollo.capability.json +120 -0
- package/capabilities/arch-backend.capability.json +97 -0
- package/capabilities/arch-client-intelligence.capability.json +401 -0
- package/capabilities/backblaze-b2.capability.json +205 -0
- package/capabilities/cal-com.capability.json +266 -0
- package/capabilities/canva.capability.json +274 -0
- package/capabilities/claude-code-routines.capability.json +172 -0
- package/capabilities/claude-managed-agents.capability.json +215 -0
- package/capabilities/client-comms-report.capability.json +246 -0
- package/capabilities/content-idea-to-production.capability.json +29 -0
- package/capabilities/datagouv.capability.json +315 -0
- package/capabilities/discord-bot.capability.json +157 -0
- package/capabilities/dropbox.capability.json +281 -0
- package/capabilities/exa.capability.json +109 -0
- package/capabilities/fal-ai.capability.json +83 -0
- package/capabilities/fal-media-lab.capability.json +158 -0
- package/capabilities/fireflies.capability.json +191 -0
- package/capabilities/freellmapi.capability.json +114 -0
- package/capabilities/generic-apikey.capability.json +92 -0
- package/capabilities/github-merge.capability.json +99 -0
- package/capabilities/github-read.capability.json +325 -0
- package/capabilities/governance-tighten-recommender.capability.json +81 -0
- package/capabilities/jev.capability.json +226 -0
- package/capabilities/lead-conversion-enrollment.capability.json +246 -0
- package/capabilities/mail-feed.capability.json +277 -0
- package/capabilities/mailgun.capability.json +52 -0
- package/capabilities/nango-google.capability.json +639 -0
- package/capabilities/notion.capability.json +417 -0
- package/capabilities/omniroute.capability.json +137 -0
- package/capabilities/posthog-analytics.capability.json +258 -0
- package/capabilities/postiz.capability.json +467 -0
- package/capabilities/proactive-digest.capability.json +190 -0
- package/capabilities/proton.capability.json +288 -0
- package/capabilities/replicate-rvm.capability.json +97 -0
- package/capabilities/research-methods.capability.json +57 -0
- package/capabilities/shopify.capability.json +395 -0
- package/capabilities/slack.capability.json +369 -0
- package/capabilities/stripe.capability.json +420 -0
- package/capabilities/telegram-bridge.capability.json +56 -0
- package/capabilities/treg.capability.json +102 -0
- package/capabilities/unipile-linkedin.capability.json +471 -0
- package/capabilities/vercel.capability.json +424 -0
- package/dist/define-CPS0n8BV.d.ts +1331 -0
- package/dist/index.d.ts +174 -900
- package/dist/index.js +26148 -23931
- package/dist/index.js.map +1 -1
- package/dist/wire.d.ts +222 -0
- package/dist/wire.js +77 -0
- package/dist/wire.js.map +1 -0
- package/package.json +27 -4
- package/packs/bookmark-views-pack.json +33 -0
- package/packs/crm-pack.json +76 -0
- package/packs/customer-profile.json +28 -0
- package/packs/deep-research.playbook.json +30 -0
- package/packs/event-views-pack.json +33 -0
- package/packs/habit-profile.json +27 -0
- package/packs/hr-pack.json +54 -0
- package/packs/invoice-profile.json +28 -0
- package/packs/knowledge-base-pack.json +56 -0
- package/packs/meeting-profile.json +29 -0
- package/packs/product-profile.json +30 -0
- package/packs/project-management-pack.json +49 -0
- package/packs/recipe-profile.json +29 -0
- package/packs/task-views-pack.json +39 -0
- package/retired.yaml +136 -0
- package/skills/app-factory-build-slice/SKILL.md +70 -0
- package/skills/app-factory-build-slice.catalog.json +17 -0
- package/skills/app-factory-design-canvas/SKILL.md +96 -0
- package/skills/app-factory-design-canvas.catalog.json +17 -0
- package/skills/app-factory-design-review/SKILL.md +99 -0
- package/skills/app-factory-design-review.catalog.json +18 -0
- package/skills/app-factory-research/SKILL.md +123 -0
- package/skills/app-factory-research.catalog.json +17 -0
- package/skills/bookmark-enrichment/SKILL.md +40 -0
- package/skills/carousel-format/carousel-format.skill.json +18 -0
- package/skills/collage-broll/collage-broll.skill.json +20 -0
- package/skills/content-taste/content-taste.skill.json +18 -0
- package/skills/creative-director/creative-director.skill.json +18 -0
- package/skills/design-critique/SKILL.md +135 -0
- package/skills/design-critique.catalog.json +12 -0
- package/skills/designing-with-real-components/SKILL.md +140 -0
- package/skills/designing-with-real-components.catalog.json +12 -0
- package/skills/edit-loop/edit-loop.skill.json +25 -0
- package/skills/facecam-edit/facecam-edit.skill.json +24 -0
- package/skills/mapping-the-server/SKILL.md +54 -0
- package/skills/math-explainer-manimgx/math-explainer-manimgx.skill.json +20 -0
- package/skills/motion-quality-gates/motion-quality-gates.skill.json +20 -0
- package/skills/open-design-edit/open-design-edit.skill.json +24 -0
- package/skills/reading-client-progress/SKILL.md +65 -0
- package/skills/routing-to-channels/SKILL.md +54 -0
- package/skills/stellar-scf-grants-advisor/ASSOCIATE-CHEATSHEET.md +133 -0
- package/skills/stellar-scf-grants-advisor/ASSOCIATE-ONBOARDING-GUIDE.md +761 -0
- package/skills/stellar-scf-grants-advisor/CLIENT-FAQ.md +181 -0
- package/skills/stellar-scf-grants-advisor/PARTNER-HANDOVER.md +130 -0
- package/skills/stellar-scf-grants-advisor/SKILL.md +102 -0
- package/skills/stellar-scf-grants-advisor/examples/README.md +43 -0
- package/skills/stellar-scf-grants-advisor/examples/chat-summary-templates.md +158 -0
- package/skills/stellar-scf-grants-advisor/examples/corpus-comparable-rows.md +136 -0
- package/skills/stellar-scf-grants-advisor/examples/q10-team-rewrites.md +109 -0
- package/skills/stellar-scf-grants-advisor/examples/q2-description-rewrites.md +88 -0
- package/skills/stellar-scf-grants-advisor/examples/q6-integration-rewrites.md +107 -0
- package/skills/stellar-scf-grants-advisor/examples/tranche-structures.md +176 -0
- package/skills/stellar-scf-grants-advisor/reference/01-methodology.md +96 -0
- package/skills/stellar-scf-grants-advisor/reference/02-scoring-framework.md +199 -0
- package/skills/stellar-scf-grants-advisor/reference/03-rejection-patterns.md +241 -0
- package/skills/stellar-scf-grants-advisor/reference/04-winner-patterns.md +120 -0
- package/skills/stellar-scf-grants-advisor/reference/05-comeback-patterns.md +92 -0
- package/skills/stellar-scf-grants-advisor/reference/06-budget-benchmarks.md +125 -0
- package/skills/stellar-scf-grants-advisor/reference/07-integration-list.md +147 -0
- package/skills/stellar-scf-grants-advisor/reference/08-abstract-fields.md +258 -0
- package/skills/stellar-scf-grants-advisor/reference/09-build-fields.md +259 -0
- package/skills/stellar-scf-grants-advisor/reference/10-corpus-winners.md +135 -0
- package/skills/stellar-scf-grants-advisor/reference/11-corpus-rejects.md +267 -0
- package/skills/stellar-scf-grants-advisor/reference/12-client-communication.md +131 -0
- package/skills/stellar-scf-grants-advisor/reference/13-excel-output-spec.md +199 -0
- package/skills/stellar-scf-grants-advisor/reference/14-worked-examples.md +160 -0
- package/skills/stellar-scf-grants-advisor/templates/abstract-review-builder.py +253 -0
- package/skills/stellar-scf-grants-advisor/templates/build-review-builder.py +213 -0
- package/skills/video-direction/video-direction.skill.json +20 -0
- package/skills/video-style-vocabulary/video-style-vocabulary.skill.json +20 -0
- package/skills/video-toolbox/video-toolbox.skill.json +20 -0
- package/src/__fixtures__/lifecycle-presets.flat-before.json +205 -0
- package/src/agency-os.yaml +122 -0
- package/src/agent-os-skill-slugs.test.ts +65 -0
- package/src/apify-social-reader.test.ts +317 -0
- package/src/base.yaml +85 -39
- package/src/blockchain-ecosystem.yaml +1 -0
- package/src/brand-library.yaml +525 -14
- package/src/builder-dev-fold.template.test.ts +113 -0
- package/src/builder.yaml +779 -91
- package/src/business-model-catalog-description.test.ts +47 -0
- package/src/business-model-grp.template.test.ts +214 -0
- package/src/business-model.yaml +296 -49
- package/src/catalog-safety.test.ts +198 -0
- package/src/catalog.template-items.test.ts +75 -0
- package/src/catalog.ts +66 -2
- package/src/concept-guard.test.ts +28 -8
- package/src/concept-guard.ts +2 -2
- package/src/content-creation.template.test.ts +52 -0
- package/src/content-creation.yaml +192 -0
- package/src/content-os.edit-loop.template.test.ts +210 -0
- package/src/content-os.publish-due-posts.template.test.ts +261 -0
- package/src/content-os.template.test.ts +322 -0
- package/src/content-os.video-takes.template.test.ts +338 -0
- package/src/content-os.work-a-take.template.test.ts +125 -0
- package/src/content-os.yaml +1830 -39
- package/src/content-studio-retired.template.test.ts +82 -0
- package/src/corpus-flow-validity.test.ts +4 -5
- package/src/crm-absorbs-outreach.template.test.ts +117 -0
- package/src/crm-build-plan.template.test.ts +128 -0
- package/src/crm-lists.template.test.ts +96 -0
- package/src/crm-messages-cadence.template.test.ts +164 -0
- package/src/crm-one-send-door.template.test.ts +65 -0
- package/src/crm.yaml +1456 -181
- package/src/decisions-wave.template.test.ts +186 -0
- package/src/define.ts +130 -17
- package/src/design-to-implementation.template.test.ts +94 -0
- package/src/domain-template-type.test.ts +75 -0
- package/src/ecosystem.yaml +27 -66
- package/src/enterprise-os.yaml +10 -134
- package/src/facecam-edit.audio-studio.test.ts +188 -0
- package/src/fal-generate-image.test.ts +200 -0
- package/src/fal-media-lab-pod-files.test.ts +180 -0
- package/src/finance.yaml +254 -1
- package/src/foundation.yaml +78 -38
- package/src/frame-host-modules.d.mts +6 -0
- package/src/frame-host-modules.mjs +58 -0
- package/src/generate.mjs +9 -3
- package/src/github-merge.test.ts +210 -0
- package/src/grants.yaml +46 -17
- package/src/hr.yaml +39 -6
- package/src/index.ts +36 -1
- package/src/intent.test.ts +161 -0
- package/src/internal-runbook.yaml +19 -1
- package/src/jev.test.ts +356 -0
- package/src/legal.yaml +33 -1
- package/src/life-os.yaml +51 -240
- package/src/lifecycle-coverage.test.ts +124 -0
- package/src/lifecycle-declarations.test.ts +252 -0
- package/src/lifecycle-presets.test.ts +468 -0
- package/src/lifecycle-presets.ts +494 -0
- package/src/lifecycle-stuck.test.ts +46 -0
- package/src/lifecycle-waits.parity.test.ts +319 -0
- package/src/marketing.yaml +108 -4
- package/src/meetings-knowledge.yaml +18 -0
- package/src/networking.yaml +23 -2
- package/src/operations.yaml +304 -4
- package/src/pipeline-views.template.test.ts +88 -0
- package/src/playbook-goal-placeholders.test.ts +57 -0
- package/src/postiz-contract.test.ts +134 -0
- package/src/presentation-declarations.test.ts +174 -0
- package/src/process-contract.validate.test.ts +352 -0
- package/src/project-management.yaml +39 -740
- package/src/publish-body.d.mts +29 -0
- package/src/publish-body.mjs +74 -0
- package/src/publish-body.test.ts +74 -0
- package/src/publish-official-lib.test.ts +176 -0
- package/src/replicate-rvm.test.ts +504 -0
- package/src/research-base.yaml +119 -20
- package/src/research-decision.yaml +60 -3
- package/src/reserved-profile-slugs.test.ts +83 -0
- package/src/retired-goal-kinds.test.ts +58 -0
- package/src/role-reference-and-step-domain.test.ts +192 -0
- package/src/seed-obligation.test.ts +1 -6
- package/src/send-message-maps.test.ts +227 -0
- package/src/shared-role-ssot.test.ts +40 -2
- package/src/ship-a-change.template.test.ts +177 -0
- package/src/skills.test.ts +170 -0
- package/src/social.yaml +85 -27
- package/src/space-packages.freshness.test.ts +97 -0
- package/src/space-packages.generated.ts +40 -0
- package/src/space-packages.test.ts +125 -0
- package/src/space-packages.ts +73 -0
- package/src/start.test.ts +188 -0
- package/src/task-intents.test.ts +293 -0
- package/src/templates.ts +20851 -21496
- package/src/types.ts +443 -60
- package/src/unipile-publish-post.test.ts +162 -0
- package/src/validate-flow.drift.test.ts +2 -3
- package/src/validate-flow.ts +22 -2
- package/src/validate-onboarding.test.ts +59 -0
- package/src/validate.test.ts +71 -4
- package/src/validate.ts +1335 -7
- package/src/wire-core.ts +231 -0
- package/src/wire.test.ts +159 -0
- package/src/wire.ts +107 -0
- package/src/agent-fleet.yaml +0 -1645
- package/src/business-developer.template.test.ts +0 -351
- package/src/business-developer.yaml +0 -860
- package/src/content-studio.yaml +0 -361
- package/src/dev-dashboard.yaml +0 -990
- package/src/outreach-comms.yaml +0 -486
- package/src/the-arch.yaml +0 -201
package/README.md
ADDED
|
@@ -0,0 +1,483 @@
|
|
|
1
|
+
# The Synap catalog
|
|
2
|
+
|
|
3
|
+
ONE home for every official installable template: workspaces, capabilities, skills,
|
|
4
|
+
packs and automations. The team sees, edits, validates and publishes them all from
|
|
5
|
+
this folder, through one lib and one CLI. The live catalog is the Control Plane's
|
|
6
|
+
`synap_packages` table, and it has one write door: `POST /api/packages` →
|
|
7
|
+
`publishPackageCore`.
|
|
8
|
+
|
|
9
|
+
> **Name today:** `synap-app/packages/workspace-templates/`, npm
|
|
10
|
+
> `@synap-core/workspace-templates`. **Planned, not done:** a rename to
|
|
11
|
+
> `packages/catalog/`, `@synap-core/catalog`, with the old name kept as a re-export
|
|
12
|
+
> shim for one release. See [Coordinated rename](#5-coordinated-rename-planned).
|
|
13
|
+
|
|
14
|
+
How installs, reconciles and tiers work is in the `synap-market` skill
|
|
15
|
+
(`synap-backend/skills/synap-market/`), which is also the agent door.
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## 1. What lives here, by kind
|
|
20
|
+
|
|
21
|
+
| Dir | Kind | Format | Published today? |
|
|
22
|
+
|---|---|---|---|
|
|
23
|
+
| `src/*.yaml` | `workspace` (and `pack`, for a suite) | Legacy workspace YAML (`meta:` plus body). A thin adapter reads it as `{kind: workspace, meta, spec}` | Yes. 31 entries, CI on every push to main |
|
|
24
|
+
| `capabilities/<key>.capability.json` | `capability` | Manifest (below). `meta` carries the listing and visibility; `spec` is the CapabilityDefinition | Yes, by hand. CI also publishes it once `SYNAP_CATALOG_LIVE_KINDS` includes `capability` (§3) |
|
|
25
|
+
| `skills/<slug>/` | `skill` | Either a manifest `<slug>.skill.json` (`creative-director`), or an Agent-Skills folder (`SKILL.md` plus references) with a header `skills/<slug>.catalog.json` beside it | The manifest: yes. A folder: only with its header, and only when it holds no reference files (a skill package carries no documents). Today one folder has a header (`designing-with-real-components`); the five moved folders have none and are **staged** |
|
|
26
|
+
| `packs/*.json` | `pack` (CP profile/view fragment) | CP `_meta` fragment | **Staged** (founder decision pending: what `pack` means). The CP's insert-only `seed-templates.ts` still owns them |
|
|
27
|
+
| `automations/<slug>.automation.json` | `automation` | bridge-setup `flowDefinition` form, plus a header `automations/<slug>.catalog.json` beside it | Only with its header, and only without apply-time placeholders. Today none has a header, so all three are **staged** (`mail-feed` also carries two placeholders bridge-setup fills) |
|
|
28
|
+
| `schema/` | | Zod manifest schema: `header.ts`, plus one body per kind (`workspace`, `capability`, `skill`, `automation`, `playbook`) | |
|
|
29
|
+
| `standards/*.standard.yaml` | | Quality standard per workspace (`pnpm eval`) | |
|
|
30
|
+
| `scripts/catalog-lib.mjs` | | **The ONE lib**: `loadCatalog` → `validateCatalog` → `diffCatalog` → `publishCatalog` | |
|
|
31
|
+
| `src/*.ts` | | The typed bundle (`dist/`) that clients ship as the zero-network fallback | |
|
|
32
|
+
|
|
33
|
+
A staged file is read, validated and counted, and the problem list carries a
|
|
34
|
+
`staged` warning for it. It cannot reach `POST /api/packages`. Today the
|
|
35
|
+
whole-catalog validate prints `✓ 73 catalog entries validated (selected: 31
|
|
36
|
+
workspace · 41 capability · 1 skill · 0 pack · 0 automation)` (41 = 35 seeded on
|
|
37
|
+
the CP + 6 authored here first).
|
|
38
|
+
|
|
39
|
+
**What stays elsewhere:**
|
|
40
|
+
- **System skills** (`system/*`) stay in `synap-backend/skills/`. They are the pod's
|
|
41
|
+
teaching substrate, seeded at boot, and are not marketplace items. Catalog files
|
|
42
|
+
may reference `system/*` slugs; the validator checks those exist when the
|
|
43
|
+
sibling repo is checked out, and says it skipped when it is not.
|
|
44
|
+
- **CLI runtime skills** (`authoring-*`, `coordinating-*`) stay in `synap-cli/templates/skills/`.
|
|
45
|
+
|
|
46
|
+
## 2. The one manifest shape
|
|
47
|
+
|
|
48
|
+
```jsonc
|
|
49
|
+
{
|
|
50
|
+
"apiVersion": "synap/v1",
|
|
51
|
+
"kind": "capability", // workspace | capability | skill | pack | automation
|
|
52
|
+
"meta": { // the header: same limits as the CP publishSchema
|
|
53
|
+
"slug": "apify", // kebab-case; dots only for a capability whose slug === spec.key
|
|
54
|
+
"name": "Apify — Web Scraping",
|
|
55
|
+
"description": "Find and run any Apify actor to collect data from public web pages and social posts. …",
|
|
56
|
+
"tags": ["capability"], "isPublic": true, "syncByDefault": true
|
|
57
|
+
// also: icon, color, domain, requiredTier, version?, owner ("template-owner" ⇔ private)
|
|
58
|
+
},
|
|
59
|
+
"spec": { "key": "apify", "skills": [ … ] }, // the per-kind body
|
|
60
|
+
"dependencies": [] // { kind, slug } — what an install pulls in
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
One pure compiler, `toPublishBody(manifest)`, turns a manifest into today's
|
|
65
|
+
`POST /api/packages` body. The CP door and its `PACKAGE_TYPES` are unchanged. A
|
|
66
|
+
workspace publishes as category `workspace`, a capability as `capability`, a skill
|
|
67
|
+
as `skill`, an automation as `workflow`.
|
|
68
|
+
|
|
69
|
+
Playbook goals use `{name}` placeholders. `@{arg:}` is refused at authoring; the
|
|
70
|
+
runtime still reads it.
|
|
71
|
+
|
|
72
|
+
## 3. Add or update, per kind
|
|
73
|
+
|
|
74
|
+
**Workspace.** Edit or add `src/<slug>.yaml`, along with its `*.template.test.ts`
|
|
75
|
+
when the template has one. Then run `pnpm --filter @synap-core/workspace-templates build`.
|
|
76
|
+
That regenerates `src/templates.ts` and `dist/`. The publish refuses a stale
|
|
77
|
+
`dist/`. **Bump `package.json` `version` whenever content changes**: the official
|
|
78
|
+
publish stamps `definition.sourcePackage.version`, and clients let a remote row win
|
|
79
|
+
only when it is strictly newer than their bundle.
|
|
80
|
+
|
|
81
|
+
**Capability.** Edit `capabilities/<key>.capability.json`. The listing and
|
|
82
|
+
visibility go in `meta`; the definition goes in `spec`.
|
|
83
|
+
- **Transition:** an **existing** capability also has a CP copy,
|
|
84
|
+
`synap-control-plane-api/src/seeds/capability-templates/<key>.capability.json`,
|
|
85
|
+
whose content must equal `spec`. Its header lives in `capability-listings.ts` and
|
|
86
|
+
`CAPABILITY_VISIBILITY` in the seeder, and must equal `meta`. Change both sides.
|
|
87
|
+
The CP tripwire `catalog-mirror.tripwire.test.ts` turns red otherwise.
|
|
88
|
+
- A **new** capability is authored here only: catalog-only files are allowed.
|
|
89
|
+
- **A reader** is an ordinary verb that reads one link: `intent: "read_webpage"`, `metadata.readOnly: true`,
|
|
90
|
+
a required `url` parameter, and `urls: [...]` declaring the links it handles (`host[/path]`, `*.host`,
|
|
91
|
+
or `"*"`; the grammar lives in `@synap-core/types/url-read`). The pod's one read door routes by those
|
|
92
|
+
patterns; nothing else names a vendor. It returns a `UrlRead` (`status`, `text`, `media`, ...), saves
|
|
93
|
+
nothing, and an account-billed one runs only on the person's tap. Reference: `apify`'s
|
|
94
|
+
`capture_social_post`. `synap catalog validate` enforces it (`skill-urls`). The agents' own door to
|
|
95
|
+
reading a link is the pod's built-in `web.read` verb (Synap Core), not a catalog capability: the old
|
|
96
|
+
`web.read` pack is retired.
|
|
97
|
+
|
|
98
|
+
**Skill.** Either a manifest `skills/<slug>/<slug>.skill.json` (`kind: skill`,
|
|
99
|
+
`spec` = the CP's `definition.skill`), or an Agent-Skills folder
|
|
100
|
+
`skills/<slug>/SKILL.md`. A folder stays in the shape `synap bridge-setup` reads; to
|
|
101
|
+
publish it, add a header BESIDE it (never inside: bridge-setup imports every file in
|
|
102
|
+
the folder as a document):
|
|
103
|
+
|
|
104
|
+
```jsonc
|
|
105
|
+
// skills/<slug>.catalog.json — a manifest without spec
|
|
106
|
+
{ "apiVersion": "synap/v1", "kind": "skill",
|
|
107
|
+
"meta": { "slug": "<slug>", "name": "Display name", "description": "listing copy", "tags": [], "isPublic": true },
|
|
108
|
+
"dependencies": [] }
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
It compiles to `definition.skill = { slug: <frontmatter name>, name: meta.name,
|
|
112
|
+
description: <frontmatter description>, kind: "instruction", scope: "pod", body }`,
|
|
113
|
+
the same slug/description/body bridge-setup imports. Refused: reference files in the
|
|
114
|
+
folder (`skill-documents`), `metadata.auto_load: true` (`skill-auto-load`), a
|
|
115
|
+
frontmatter name that is not `meta.slug` (`skill-slug`). Without a header the folder
|
|
116
|
+
is staged. Deciding which folders get a header (their listing and visibility) is a
|
|
117
|
+
content decision; `reading-client-progress` and `stellar-scf-grants-advisor` are
|
|
118
|
+
client-specific.
|
|
119
|
+
- **Transition:** the five moved folders (`bookmark-enrichment`,
|
|
120
|
+
`mapping-the-server`, `reading-client-progress`, `routing-to-channels`,
|
|
121
|
+
`stellar-scf-grants-advisor`) must stay byte-identical to
|
|
122
|
+
`synap-cli/templates/skills/<slug>/`, because `bridge-setup` still reads them
|
|
123
|
+
there. The guard is the CLI's `test/catalog-mirror.tripwire.test.ts`.
|
|
124
|
+
|
|
125
|
+
**Pack.** `packs/*.json` must stay byte-identical to the CP's `templates/packs/`
|
|
126
|
+
(CP tripwire).
|
|
127
|
+
|
|
128
|
+
**Automation.** Either a manifest (`kind: automation`, `spec` in the authoring
|
|
129
|
+
`flow` form), or a raw `automations/<slug>.automation.json` in the `flowDefinition`
|
|
130
|
+
form bridge-setup reads, published once a header `automations/<slug>.catalog.json`
|
|
131
|
+
(`kind: "automation"`, no `spec`) sits beside it. It publishes as category
|
|
132
|
+
`workflow`: `definition = { profiles: [], automations: [{ key: <slug>, name,
|
|
133
|
+
description?, triggerType, triggerConfig, flowDefinition, status }] }`, i.e. the raw
|
|
134
|
+
file minus its `metadata` notes. Refused: an apply-time placeholder
|
|
135
|
+
(`apply-time-placeholder`: an empty or `<…>` connection id, a `<…>` output channel,
|
|
136
|
+
a skill node without `skillId`) and any raw key a package cannot carry (`state`).
|
|
137
|
+
Transition: the three raw files must stay byte-identical to
|
|
138
|
+
`synap-cli/templates/automations/` (CLI tripwire).
|
|
139
|
+
|
|
140
|
+
**Every kind.** Run the gate before you push:
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
cd synap-app
|
|
144
|
+
node_modules/.bin/vitest run packages/workspace-templates # schema, parity, lifecycle, goal grammar
|
|
145
|
+
pnpm --filter @synap-core/workspace-templates type-check:catalog # schema/ + scripts/
|
|
146
|
+
synap catalog validate # the whole corpus, offline
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
The lib needs Node ≥ 22.18, because it imports `schema/*.ts` through native type
|
|
150
|
+
stripping. An older Node refuses with `unsupported-runtime`.
|
|
151
|
+
|
|
152
|
+
## Retiring a template
|
|
153
|
+
|
|
154
|
+
A template that leaves the catalog is **not** just deleted: it gets a tombstone in
|
|
155
|
+
`retired.yaml` (schema `schema/retired.ts`), so a pod can tell "retired, replaced by
|
|
156
|
+
X" from "never heard of it" and offer the person a safe move to X.
|
|
157
|
+
|
|
158
|
+
1. Delete the file (`src/<slug>.yaml`, `capabilities/<key>.capability.json`, …).
|
|
159
|
+
2. Add an entry to `retired.yaml`:
|
|
160
|
+
```yaml
|
|
161
|
+
- slug: radar
|
|
162
|
+
kind: workspace # default; capability · skill · pack · automation
|
|
163
|
+
replacedBy: ecosystem # a LIVE slug of the same kind, or omit when nothing replaces it
|
|
164
|
+
reason: Radar was merged into Ecosystem, which tracks competitors and trends in one place.
|
|
165
|
+
since: "2026-07-16"
|
|
166
|
+
```
|
|
167
|
+
3. `synap catalog validate`: `replacedBy` must be live and not retired, no slug may be
|
|
168
|
+
both live and retired **in the same category** (the CP keys rows on slug + category,
|
|
169
|
+
so a retired workspace `posthog-analytics` beside a live capability of that slug is
|
|
170
|
+
fine), and the reason must be one plain sentence a person reads.
|
|
171
|
+
4. Publish as usual. `publishCatalog` sends each tombstone of the selected kinds to
|
|
172
|
+
`POST /api/packages/retire` through the catalog door, **after** the live publishes
|
|
173
|
+
(a replacement published in the same run exists by then; a tombstone whose
|
|
174
|
+
replacement failed is not sent). The preview prints `retire radar → ecosystem` with
|
|
175
|
+
its status: `new` (no CP row, a tombstone row is created), `changed` (the live row is
|
|
176
|
+
retired, or its retirement updated), `unchanged` (not sent). A CP without the endpoint
|
|
177
|
+
is reported as such, never skipped silently.
|
|
178
|
+
|
|
179
|
+
Removing an entry from `retired.yaml` does not un-retire the CP row. The evidence
|
|
180
|
+
behind each seeded entry is in the pod file `00c1b2fe-ef98-41fa-86cf-801dfab12cd1` ("Template lifecycle: decisions wave + lane catalog").
|
|
181
|
+
|
|
182
|
+
## Removing a kind from a live template
|
|
183
|
+
|
|
184
|
+
`retired.yaml` tombstones a whole template, not a kind inside one. There is no
|
|
185
|
+
kind-level tombstone: remove the `profiles:` entry and everything that names it
|
|
186
|
+
(views, relations, entity bento, onboarding `collect`, standards), bump the
|
|
187
|
+
`package.json` version (minor for a removed kind), and republish. A pod that already
|
|
188
|
+
installed the template keeps its profile and entities (profiles are never removed from
|
|
189
|
+
an installed pod); only new installs lose the kind. The kinds removed this way are
|
|
190
|
+
listed in `src/retired-goal-kinds.test.ts`, which fails if a template declares one again
|
|
191
|
+
(Life OS `goal`, Enterprise OS `objective`, Project Management `okr`: "Goal" is the
|
|
192
|
+
pod's track, decision D2, 2026-10-23).
|
|
193
|
+
|
|
194
|
+
## Writing a process (a playbook that follows a kind's lifecycle)
|
|
195
|
+
|
|
196
|
+
The status belongs to the **kind or role**, never to a playbook. Its profile declares the lifecycle ONCE, in its
|
|
197
|
+
template:
|
|
198
|
+
|
|
199
|
+
```yaml
|
|
200
|
+
lifecycle:
|
|
201
|
+
property: post-status
|
|
202
|
+
options:
|
|
203
|
+
- { key: Idea, category: open }
|
|
204
|
+
- { key: Published, category: done }
|
|
205
|
+
- { key: Archived, category: lost, humanOnly: true }
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
Every option has one category (`open · active · paused · done · lost`); rules read the category, names stay free.
|
|
209
|
+
`humanOnly` marks an option no agent sets; an agent's move into `done` or `lost` proposes. Every move goes through
|
|
210
|
+
the one status door (`moveStatus`; an agent sends `update_entity` with `expectedStatus`).
|
|
211
|
+
|
|
212
|
+
A step that can still move may also say when it is late and what it waits on, by the pod's own rules
|
|
213
|
+
(`lifecycleOptionWaitsProblems` in `src/validate.ts`; never on a done or lost option):
|
|
214
|
+
|
|
215
|
+
```yaml
|
|
216
|
+
- key: sent
|
|
217
|
+
category: active
|
|
218
|
+
dateBinding: dueDate # late once this date passes while it stands here
|
|
219
|
+
waits: { on: external, waitKind: payment, refFrom: clientId, dateBinding: dueDate }
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
`dateBinding` and `waits.refFrom` / `waits.dateBinding` are property slugs. `waits.on` is a hold's `on` (person ·
|
|
223
|
+
agent · external · thing · decision · date · nobody); `waitKind` one of the pod's `WAIT_KINDS`.
|
|
224
|
+
|
|
225
|
+
A new lifecycle should adopt one of the ten bases (`src/lifecycle-presets.ts`: work-item, run, decision, asset,
|
|
226
|
+
publication, agreement, pipeline, relationship, offering, initiative) and say only how it differs:
|
|
227
|
+
|
|
228
|
+
```yaml
|
|
229
|
+
lifecycle:
|
|
230
|
+
property: reference-status
|
|
231
|
+
adopts: asset
|
|
232
|
+
rename: { in-review: studied, deprecated: archived } # base key → this kind's key
|
|
233
|
+
drop: [] # base keys this kind does not use
|
|
234
|
+
add: [] # { key, category, after | before }
|
|
235
|
+
humanOnly: {} # per step; false removes a base's mark
|
|
236
|
+
stuckAfterDays: {} # per step
|
|
237
|
+
dateBinding: {} # per step: { sent: dueDate }
|
|
238
|
+
waits: {} # per step: { sent: { on: external } }
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
The build compiles it into the flat `options` above and writes the select's `enumValues` when the YAML leaves them
|
|
242
|
+
out; nothing new reaches the pod. A lifecycle whose order the bases cannot express stays flat.
|
|
243
|
+
|
|
244
|
+
A playbook that works that lifecycle is a **process**: it FOLLOWS it. Its stages name options of it, its workers
|
|
245
|
+
start on it, and a person decides at the moments that commit the business. It never keeps a second status field.
|
|
246
|
+
The reference is Content OS "Produce Content" (`synap-app/packages/workspace-templates/src/content-os.yaml`).
|
|
247
|
+
|
|
248
|
+
**Official vs pod-local.** An official template or capability lives ONLY in the catalog
|
|
249
|
+
(`synap-app/packages/workspace-templates/`, by kind) and is published with
|
|
250
|
+
`synap catalog publish --official` (CI on main). A playbook, kind or automation an agent creates on a pod
|
|
251
|
+
(`synap_create_playbook`, `synap_define_kind`, …) is **pod-local**: it never reaches the catalog. To make it
|
|
252
|
+
official, write it into the catalog file and publish.
|
|
253
|
+
|
|
254
|
+
| Field | Where | Rule |
|
|
255
|
+
|---|---|---|
|
|
256
|
+
| `subjectProfile.profileSlug` | playbook | The kind or role the process works. |
|
|
257
|
+
| `subjectProfile.statusProperty` | playbook | Omit it: the pod follows the profile's declared lifecycle. If you name it, name that same property. A status worker on a role with no declared lifecycle is refused. |
|
|
258
|
+
| `stages[].subjectStatus` | stage | Entering the stage moves the subject to this option, through the door. Must be an **existing option** of the lifecycle — never invent one. |
|
|
259
|
+
| `stages[].gate` | stage | `{kind: human}` at every commitment: send to a client, sign, pay, publish, won/lost, anything irreversible. `{kind: check}` only where the stage's own criteria can be verified. A gated stage writes its status only when the gate passes. A check gate judges the stage being LEFT, so never use it to guard an irreversible status. |
|
|
260
|
+
| `stages[].onFail` | stage | `{toStage: <key>}` — where a rejected gate sends the run (rework loop). |
|
|
261
|
+
| `stages[].criteria` | stage | 2–5 binary statements; `check.kind` evidence (cheapest) · capability · judge · human. |
|
|
262
|
+
| `expectedOutputs[]` | stage or playbook | What the step must produce: `kind` + `label` + `relationToSubject` (an existing relation slug, or `none`). The UI shows what was produced from this. |
|
|
263
|
+
| `activators[]` (workers) | playbook | `on`: `created` · `enters_status` (+ `status`) · `count` (+ `status`, `min` ≥ 2) · `schedule` (+ `cron`, UTC) · `manual`. `size`: `per_thing` (default) · `per_moment` (count and schedule always are). `mode`: `propose` (default) · `run` only when cheap and safe. `maxPendingApprovals` (default 20) throttles. Compiled to a governed rule the owner can pause; it fires once per thing per transition. |
|
|
264
|
+
| `humanOnlyStatuses` | playbook | Legacy: the options no stage owns. Mark a person-only option `humanOnly` on the lifecycle instead; while `statusProperty` is set, `synap catalog validate` still checks that stages and this list cover every option. |
|
|
265
|
+
| `goalTemplate` | playbook | Placeholders are `{paramName}`. Never `@{arg:…}` (read-only legacy). |
|
|
266
|
+
| `params` | playbook | The subject is a `type: entity` param. A required param left unanswered becomes a question owed by the person, not an empty string. |
|
|
267
|
+
|
|
268
|
+
Human moments use an `ask` on an owed slot: `confirm` / `choose` (one `recommended`) / `form` / `act` / `provide`
|
|
269
|
+
(connection, file or secret through the vault). Never ask for a secret in a form.
|
|
270
|
+
|
|
271
|
+
Validation: `synap catalog validate` (process contract, goal grammar, lifecycle coverage ratchet — the count of
|
|
272
|
+
lifecycle kinds with no process may only go down).
|
|
273
|
+
|
|
274
|
+
## Intent: what a space produces
|
|
275
|
+
|
|
276
|
+
A space is named by its PURPOSE first ("Product · Dev", "Sales · CRM") and is read through the THINGS it makes.
|
|
277
|
+
The template that owns the space says both, in `meta.intent`:
|
|
278
|
+
|
|
279
|
+
```yaml
|
|
280
|
+
meta:
|
|
281
|
+
intent:
|
|
282
|
+
label: Product # the purpose word, ≤ 24 characters
|
|
283
|
+
produces: # ordered; kinds or roles
|
|
284
|
+
- profile: devplane_feature
|
|
285
|
+
- profile: devplane_story
|
|
286
|
+
- profile: ui-design
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
- **Several kinds, never one only.** List what a person would come to the space to see move, in the order a home
|
|
290
|
+
shows them.
|
|
291
|
+
- **No `produces` (or `[]`) = a library.** Brand, Strategy, Ecosystem, Knowledge… are read, not moved: they carry
|
|
292
|
+
a label only.
|
|
293
|
+
- **Each produced profile declares a lifecycle** — a home counts things by lifecycle category, so a kind without
|
|
294
|
+
one cannot be counted (`intent-no-lifecycle`, naming it). Declare the lifecycle first (see "Writing a process").
|
|
295
|
+
- **Each produced profile is the template's own or one it depends on** (`require`/`compose` closure), e.g. CRM
|
|
296
|
+
produces the `lead` and `client` roles whose lifecycles `foundation` declares (`intent-profile-unknown`).
|
|
297
|
+
- **Only a template that owns a space declares it.** An overlay (`compose`) layers onto its base's space and a
|
|
298
|
+
pack (`suite`) owns none, so neither carries an intent (`intent-no-workspace`); `base` carries none either
|
|
299
|
+
(it is seeded into every space).
|
|
300
|
+
- **On the pod.** Both install doors forward it as a top-level `intent` (never in `_meta`, which the CP rebuilds
|
|
301
|
+
on serve); the pod keeps it in `workspaces.settings.intent`. A space with no declared intent gets one inferred at
|
|
302
|
+
read time (the profiles there that declare a lifecycle and hold things), never stored.
|
|
303
|
+
|
|
304
|
+
## 4. The ONE command set
|
|
305
|
+
|
|
306
|
+
```bash
|
|
307
|
+
synap catalog validate [--kind k] [slug...] # offline: per-kind schema, cross-kind refs, goal grammar, duplicates
|
|
308
|
+
synap catalog diff [--kind k] [slug...] # vs the live CP: new / changed / unchanged (+ warnings)
|
|
309
|
+
synap catalog publish --official [--kind k] [slug...] [--dry-run] [--yes] [--json]
|
|
310
|
+
synap market publish --official [slug...] [--dry-run] # alias of: catalog publish --official --kind workspace
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
- `publish` requires `--official` and a `synap login` session that owns the
|
|
314
|
+
`synap-official` vendor. The CLI checks the publisher (`checkPublisher`) **before**
|
|
315
|
+
it shows the diff. A non-official account is refused up front. A failed read is
|
|
316
|
+
reported as `cp-unreachable`, never as "not official". `diff` warns instead of
|
|
317
|
+
refusing.
|
|
318
|
+
- `publish` validates the **whole corpus** and stops on any error. It then shows the
|
|
319
|
+
diff, asks y/N, and writes only after you confirm. `--dry-run` stops after the
|
|
320
|
+
preview. Warnings never block.
|
|
321
|
+
- A selection (`--kind`, slugs) narrows what gets planned and published. Validation
|
|
322
|
+
always covers the whole corpus, so a workspace's `dependencies` still resolve.
|
|
323
|
+
- The CLI finds the checkout by package name (`@synap-core/catalog` first, then
|
|
324
|
+
`@synap-core/workspace-templates`), or by `--catalog-dir`. Every error code maps
|
|
325
|
+
to a single next step (`hint` in `--json`).
|
|
326
|
+
|
|
327
|
+
**CI** (`synap-app/.github/workflows/publish-official-templates.yml`, through the
|
|
328
|
+
wrapper `scripts/publish-official.mjs`, which uses the same lib):
|
|
329
|
+
|
|
330
|
+
| Event | What runs |
|
|
331
|
+
|---|---|
|
|
332
|
+
| PR touching the catalog | Job `validate` only: build, validate every kind, print the **offline** preview (each entry and the version the CP will derive, where knowable offline). It holds **no secret and no `id-token`**: a PR runs its own lockfile and scripts. Guarded by `scripts/publish-workflow.guard.test.ts`. |
|
|
333
|
+
| Push to `main` (or manual) | `validate`, then job `publish` (environment `catalog-publish`): a read-only preview against the live CP, then publish live `--kind ${SYNAP_CATALOG_LIVE_KINDS:-workspace}`, then npm publish, only if the `package.json` version is new on npm. |
|
|
334
|
+
|
|
335
|
+
`SYNAP_CATALOG_LIVE_KINDS` is a repository **variable**. While it is unset, main
|
|
336
|
+
publishes workspaces only: every kind is still validated and previewed, but only
|
|
337
|
+
workspaces are written. Set it to `workspace,capability,skill,pack,automation`
|
|
338
|
+
only after runbook §5 A. Secrets: `SYNAP_CP_URL`, `SYNAP_CP_PUBLISH_TOKEN`
|
|
339
|
+
(a CP PAT of the `synap-official` owner; humans use `synap login`), `NPM_TOKEN`.
|
|
340
|
+
|
|
341
|
+
**One-time setup of the `catalog-publish` environment** (GitHub → synap-app →
|
|
342
|
+
Settings → Environments):
|
|
343
|
+
1. Create the environment `catalog-publish`.
|
|
344
|
+
2. Deployment branches and tags: **Selected branches → `main`** only.
|
|
345
|
+
3. Add the environment secrets `SYNAP_CP_PUBLISH_TOKEN` and `SYNAP_CP_URL`.
|
|
346
|
+
4. **Delete** the repository-level `SYNAP_CP_PUBLISH_TOKEN` (and `SYNAP_CP_URL`)
|
|
347
|
+
secrets, so no other job, and no workflow a branch pusher writes, can read them.
|
|
348
|
+
`NPM_TOKEN` may stay a repository secret (it is read only by the same job).
|
|
349
|
+
Until step 3 is done, the `publish` job has no token: it validates and leaves a
|
|
350
|
+
`::warning::`, it never publishes.
|
|
351
|
+
|
|
352
|
+
**The CP never reseeds on deploy.** `deploy.sh`, `update.sh` and ops `apply` no
|
|
353
|
+
longer run `seed:capabilities` or `seed:templates`. Both seeders are **insert-only
|
|
354
|
+
bootstraps** for an empty CP, run by hand: they skip any slug that already has a
|
|
355
|
+
row. A tripwire (`no-template-reseed-on-deploy-tripwire.test.ts`) guards this.
|
|
356
|
+
**Official capability keys are reserved:** a non-official publish of an official
|
|
357
|
+
key gets 409 `OFFICIAL_CAPABILITY_KEY_RESERVED`, and the CP serves the official row
|
|
358
|
+
first for a key.
|
|
359
|
+
|
|
360
|
+
**Transition mirrors** (each retires in the same change that deletes its copies; see §5).
|
|
361
|
+
These guards are **local-only**: each skips when the sibling repo is not checked out,
|
|
362
|
+
and every repo's CI checks out itself alone, so CI does not enforce them. Run them
|
|
363
|
+
on a full monorepo checkout before merging a change to either side. The same holds
|
|
364
|
+
for `schema/header.mirror.tripwire.test.ts` (header limits ↔ the CP `publishSchema`)
|
|
365
|
+
and `scripts/catalog-lib.columns.tripwire.test.ts` (the preview's columns and
|
|
366
|
+
adoption rule ↔ the CP publish core); their CI-safe halves are snapshots.
|
|
367
|
+
|
|
368
|
+
| Copy | Guard | Retires when |
|
|
369
|
+
|---|---|---|
|
|
370
|
+
| CP `src/seeds/capability-templates/*.capability.json` + listings/visibility | CP `src/seeds/catalog-mirror.tripwire.test.ts` (spec- and meta-equal) | the CP pin is bumped and the seeder reads the package |
|
|
371
|
+
| CP `templates/packs/*.json` | same file (byte-equal) | same |
|
|
372
|
+
| CLI `templates/skills/<5 moved>/`, `templates/automations/*.automation.json` | CLI `test/catalog-mirror.tripwire.test.ts` (byte-equal, both directions) | the CLI's pin admits a package release that ships them: `bridge-setup` already reads the installed package first, and the CLI's retirement test fails while both exist |
|
|
373
|
+
|
|
374
|
+
## 5. Founder runbook: deploy, publish, retire the copies
|
|
375
|
+
|
|
376
|
+
Do these in order. The runbook only names the commands; it does not run anything.
|
|
377
|
+
|
|
378
|
+
### A. Turn on catalog-published capabilities
|
|
379
|
+
|
|
380
|
+
1. **Pre-flight on the prod CP DB.** Both queries must return 0 rows. If either
|
|
381
|
+
does not, resolve the duplicates first.
|
|
382
|
+
```sql
|
|
383
|
+
SELECT lower(definition->'capability'->>'key') k, count(*)
|
|
384
|
+
FROM packages WHERE category = 'capability' GROUP BY 1 HAVING count(*) > 1;
|
|
385
|
+
SELECT slug, count(*)
|
|
386
|
+
FROM packages WHERE category = 'capability' GROUP BY 1 HAVING count(*) > 1;
|
|
387
|
+
```
|
|
388
|
+
2. **Deploy the backend first:** `26638d5e` ("an unanswered optional declared param
|
|
389
|
+
renders empty") must be live on the pods before any playbook goal written as
|
|
390
|
+
`{name}` reaches them; otherwise a literal `{programName}` lands in agent prompts.
|
|
391
|
+
Order: **backend → CP → dry run → publish.**
|
|
392
|
+
3. **Deploy the CP** with all of these commits in that one deploy:
|
|
393
|
+
- `b669f90a`: posthog listing.
|
|
394
|
+
- `7ff44bf9`: capabilities publish onto their seeded row (official adoption, `syncByDefault`, dotted slug, description up to 10,000, full-column compare).
|
|
395
|
+
- `dac1da23`: reserved official keys, official-first read.
|
|
396
|
+
- `fe56bdf6`: reseed retired, seeder is insert-only.
|
|
397
|
+
- `d7a3f401`: ops drift is a human step.
|
|
398
|
+
- `0b0be3c8`: a capability key's owner is resolved before visibility; a key is a string equal to its slug.
|
|
399
|
+
- `a1401509`: an official publish adopts by the adoption rule, never a row of another kind.
|
|
400
|
+
- `6417b9f9`: `GET /api/packages/:slug?category=` serves the row a publish writes (the preview reads it).
|
|
401
|
+
|
|
402
|
+
Never ship `fe56bdf6` without `7ff44bf9` and `dac1da23`: on the old door, a catalog
|
|
403
|
+
publish forks every seeded row. This deploy no longer reseeds, so the rows stay
|
|
404
|
+
as the last reseed left them.
|
|
405
|
+
4. **Dry run**, signed in as the official publisher (a private row is invisible to
|
|
406
|
+
an anonymous read): `synap catalog publish --official --kind capability --dry-run`.
|
|
407
|
+
The preview compares each body with the row the publish WRITES (the CP's adoption
|
|
408
|
+
rule) on the content version AND every column the CP writes, and prints a
|
|
409
|
+
content change as `~ definition: new content version` and each changed column
|
|
410
|
+
as `~ column: before → after`.
|
|
411
|
+
5. **Read the diff.** Expected, and NOT a reason to stop:
|
|
412
|
+
- The **seeded capabilities** each show `CHANGED` with the same `h-` version and
|
|
413
|
+
only `~ source: "file-seed" → "api"`: the first publish writes each row once.
|
|
414
|
+
- **arch-client-intelligence** and **proton** show `CHANGED` with a new version (3 playbooks: Propose Grant Submission, Call Prep Brief, Draft Reply):
|
|
415
|
+
their playbook goals moved to the `{name}` grammar (`84363910`), which the
|
|
416
|
+
retired reseed never shipped.
|
|
417
|
+
- **posthog-analytics** shows `CHANGED` on its listing columns (`b669f90a`).
|
|
418
|
+
- **canva, dropbox, notion, slack, vercel** show `CHANGED` with a new version:
|
|
419
|
+
they have been official rows since 2026-10-01 (published from the old root
|
|
420
|
+
copies), and the catalog copy is newer (a derived `provides`, `72dd8d66`, and
|
|
421
|
+
reconciled descriptions). Their `~ tags` line shows only the AUTHORED tags
|
|
422
|
+
(`["capability"]`): the CP appends the search tokens it derives from the
|
|
423
|
+
definition, so the row keeps its search words and gains `capability` first.
|
|
424
|
+
- **content-idea-to-production** shows `CHANGED` on its definition and
|
|
425
|
+
description: the "Retired" listing the reseed never shipped.
|
|
426
|
+
- **claude-code-routines** is `NEW`. Publish it early: until an official row
|
|
427
|
+
exists, its key can be claimed by anyone.
|
|
428
|
+
- Any other `changed` row, or a warning that the CP ignores `?category=` (an
|
|
429
|
+
older CP): **STOP** and look.
|
|
430
|
+
6. **Publish:** `synap catalog publish --official --kind capability`. Confirm at the
|
|
431
|
+
prompt.
|
|
432
|
+
7. **Widen CI:** set the repo variable
|
|
433
|
+
`SYNAP_CATALOG_LIVE_KINDS=workspace,capability,skill,automation`. A skill folder
|
|
434
|
+
or raw automation publishes only once it has a header; `pack` stays out until
|
|
435
|
+
its meaning is decided.
|
|
436
|
+
8. On a **brand-new, empty** CP only: run
|
|
437
|
+
`docker compose -f docker-compose.prod.yml run --rm control-plane pnpm seed:capabilities`
|
|
438
|
+
(and `seed:templates`) once, then step 6.
|
|
439
|
+
|
|
440
|
+
### B. Publish the package and retire the mirrors
|
|
441
|
+
|
|
442
|
+
1. **Publish the package to npm.** Merge a version bump to main, and CI publishes
|
|
443
|
+
it. Local is `0.13.0` and npm has `0.12.0`, so `check-publish-freshness` is red
|
|
444
|
+
until then. Never run `npm publish` by hand.
|
|
445
|
+
2. **Bump the pins** and refresh each repo's own lockfile:
|
|
446
|
+
- **CP:** `^0.12.0` → `>=0.13.0 <1.0.0`. The caret excludes 0.13. Do this only
|
|
447
|
+
once the CP `pnpm-lock.yaml` is no longer peer-dirty.
|
|
448
|
+
- **CLI:** `>=0.12.0 <1.0.0`, which already admits 0.13. Refresh with
|
|
449
|
+
`pnpm install --lockfile-only --ignore-workspace` so the root lockfile is not
|
|
450
|
+
touched.
|
|
451
|
+
- **Backend:** `packages/api` **and** `apps/api` (`>=0.11.0 <1.0.0`). Move the
|
|
452
|
+
floor up only if a consumer needs the new content.
|
|
453
|
+
3. **Point the readers at the package:**
|
|
454
|
+
- the CP seeder and capability resolver (`capability-template-dir.ts`) read
|
|
455
|
+
`node_modules/@synap-core/workspace-templates/capabilities/`, plus `packs/` for
|
|
456
|
+
`seed-templates.ts`;
|
|
457
|
+
- `synap bridge-setup` installs the published skill and automation entries
|
|
458
|
+
through the pod instead of reading `templates/`.
|
|
459
|
+
4. **Delete the copies and their tripwires in the same change:**
|
|
460
|
+
- CP: `src/seeds/capability-templates/`, `templates/packs/`, the listing and
|
|
461
|
+
visibility literals, and `catalog-mirror.tripwire.test.ts`;
|
|
462
|
+
- CLI: the five moved skill folders, `templates/automations/`, and
|
|
463
|
+
`test/catalog-mirror.tripwire.test.ts`.
|
|
464
|
+
|
|
465
|
+
### C. Coordinated rename (planned)
|
|
466
|
+
|
|
467
|
+
Rename `packages/workspace-templates` to `packages/catalog` (`@synap-core/catalog`)
|
|
468
|
+
in one change, at a quiet moment, because every tree's `node_modules` links move:
|
|
469
|
+
|
|
470
|
+
1. `git mv synap-app/packages/workspace-templates synap-app/packages/catalog`.
|
|
471
|
+
2. Update **both** workspace files: the root `pnpm-workspace.yaml`
|
|
472
|
+
(`synap-app/packages/workspace-templates`) and `synap-app/pnpm-workspace.yaml`
|
|
473
|
+
(`packages/workspace-templates`).
|
|
474
|
+
3. Change the `package.json` `name` to `@synap-core/catalog`. Ship a thin
|
|
475
|
+
`@synap-core/workspace-templates` shim that re-exports it for one release. The
|
|
476
|
+
backend pins `>=0.11 <1`, the CP `^0.12`, the CLI `>=0.12 <1`, and the
|
|
477
|
+
synap-app/browser consumers use `workspace:*`.
|
|
478
|
+
4. Update the workflow paths and `--filter` in `publish-official-templates.yml`,
|
|
479
|
+
and the `ci.yml` freshness step.
|
|
480
|
+
5. Run `pnpm install` in each tree: the monorepo root, `synap-app/`, and each
|
|
481
|
+
sibling that installs on its own. Then run every consumer's typecheck.
|
|
482
|
+
6. The CLI and both tripwires already resolve `packages/catalog` first. Remove the
|
|
483
|
+
`workspace-templates` fallback once the shim is retired.
|