@synap-core/workspace-templates 0.11.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 +189 -900
- package/dist/index.js +24654 -21639
- 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 +41 -27
- 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.template.test.ts +25 -19
- package/src/base.yaml +95 -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 +798 -92
- 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 +598 -0
- package/src/catalog-safety.test.ts +198 -0
- package/src/catalog.template-items.test.ts +75 -0
- package/src/catalog.ts +85 -2
- package/src/civic-france.yaml +102 -0
- 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/dist-freshness.test.ts +97 -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 +130 -28
- 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 +57 -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 +65 -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 +176 -0
- package/src/send-message-maps.test.ts +227 -0
- package/src/shared-role-ssot.test.ts +42 -1
- 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 +21639 -21522
- 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 +32 -2
- package/src/validate-onboarding.test.ts +59 -0
- package/src/validate.test.ts +156 -3
- package/src/validate.ts +1384 -7
- package/src/wire-core.ts +231 -0
- package/src/wire.test.ts +159 -0
- package/src/wire.ts +107 -0
- package/src/__fixtures__/report-automation-flow.json +0 -393
- 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/src/grants.yaml
CHANGED
|
@@ -67,6 +67,14 @@ profiles:
|
|
|
67
67
|
color: blue
|
|
68
68
|
description: A single grant application — one project, one round, one outcome. The pipeline card and analysis unit.
|
|
69
69
|
scope: WORKSPACE
|
|
70
|
+
# The ONE lifecycle (work model L1): every option's category.
|
|
71
|
+
lifecycle:
|
|
72
|
+
property: stage
|
|
73
|
+
options:
|
|
74
|
+
- { key: scope, category: open }
|
|
75
|
+
- { key: abstract, category: active }
|
|
76
|
+
- { key: build, category: active }
|
|
77
|
+
- { key: awaiting-results, category: active }
|
|
70
78
|
properties:
|
|
71
79
|
# Pipeline + workflow state
|
|
72
80
|
- slug: stage
|
|
@@ -693,6 +701,15 @@ profiles:
|
|
|
693
701
|
applicableKinds:
|
|
694
702
|
- person
|
|
695
703
|
- company
|
|
704
|
+
# The ONE lifecycle (work model L1): every option's category.
|
|
705
|
+
lifecycle:
|
|
706
|
+
property: clientStatus
|
|
707
|
+
options:
|
|
708
|
+
- { key: prospect, category: open }
|
|
709
|
+
- { key: active, category: active }
|
|
710
|
+
- { key: paused, category: paused }
|
|
711
|
+
- { key: former, category: done }
|
|
712
|
+
- { key: churned, category: lost }
|
|
696
713
|
properties:
|
|
697
714
|
- slug: clientStatus
|
|
698
715
|
label: Status
|
|
@@ -844,16 +861,12 @@ profiles:
|
|
|
844
861
|
|
|
845
862
|
views:
|
|
846
863
|
- name: Pipeline
|
|
847
|
-
|
|
864
|
+
# The ONE board (work model L3, D3): columns ARE the submission's declared
|
|
865
|
+
# lifecycle (`stage`), moves go through the one mover.
|
|
866
|
+
type: pipeline
|
|
848
867
|
scopeProfileSlug: grant_submission
|
|
849
868
|
config:
|
|
850
|
-
|
|
851
|
-
cardFields:
|
|
852
|
-
- summary
|
|
853
|
-
- requestedAmount
|
|
854
|
-
- awardedAmount
|
|
855
|
-
- outcome
|
|
856
|
-
- status
|
|
869
|
+
profileSlug: grant_submission
|
|
857
870
|
- name: Submissions
|
|
858
871
|
type: table
|
|
859
872
|
scopeProfileSlug: grant_submission
|
|
@@ -983,8 +996,8 @@ entityLinks:
|
|
|
983
996
|
# trancheModel, nextDeadline) are READ from the `grantProgram` entity at runtime,
|
|
984
997
|
# NOT hardcoded per chain — so one playbook serves Stellar SCF, Optimism RetroPGF,
|
|
985
998
|
# etc. Only a genuinely different-SHAPED program later earns its own override
|
|
986
|
-
# playbook (base + data-driven-override decision). Generalizes the
|
|
987
|
-
# advisor
|
|
999
|
+
# playbook (base + data-driven-override decision). Generalizes the retired
|
|
1000
|
+
# Stellar staged advisor capability into a template (it was removed, D5). Bound to `contract` (the
|
|
988
1001
|
# engagement, per decision — NOT company); targets a `grant-program` param — the
|
|
989
1002
|
# 3-layer spine (contract → grant-program → round → grant_submission) made runnable.
|
|
990
1003
|
playbooks:
|
|
@@ -1020,15 +1033,29 @@ playbooks:
|
|
|
1020
1033
|
params:
|
|
1021
1034
|
- { name: contract, type: entity, profileSlug: contract, label: Engagement, required: true }
|
|
1022
1035
|
- { name: grantProgram, type: entity, profileSlug: grant-program, label: Grant Program, required: true }
|
|
1036
|
+
# A grant pursuit is an ENGAGEMENT with a before/during/after lifecycle that
|
|
1037
|
+
# outlives any one working session (drafting, then weeks of waiting on the
|
|
1038
|
+
# funder, then tranche delivery), so this is a PROJECT template: its stages
|
|
1039
|
+
# coordinate a long-running container rather than script one focus session.
|
|
1040
|
+
scope: project
|
|
1023
1041
|
# Generic stages, mapped onto grant_submission's own stage/status/outcome +
|
|
1024
1042
|
# tranche vocab so the run can maintain the card as it advances.
|
|
1043
|
+
# `category` is the closed rollup bucket (backlog|planned|started|paused|
|
|
1044
|
+
# completed|canceled), chosen by MEANING: `identify` is pre-commitment
|
|
1045
|
+
# scoping (planned); `awaiting` is genuinely blocked on the funder (paused);
|
|
1046
|
+
# `awarded` stays `started` because delivery follows an award — a rejected
|
|
1047
|
+
# pursuit's terminality lives on the submission's own `outcome` field, not
|
|
1048
|
+
# here.
|
|
1049
|
+
# Every step is worked where the grant submissions live: grants composes
|
|
1050
|
+
# onto Operations, so the DOMAIN is `operations` (the workspace template
|
|
1051
|
+
# slug the workspace carries — an overlay's own slug is never a domain).
|
|
1025
1052
|
stages:
|
|
1026
|
-
- { key: identify, name: Identify, description: "Understand the project and which of the program's submission tracks fit — before any writing.", goal: "A clear project understanding and the fitting submission track; submission stage = scope." }
|
|
1027
|
-
- { key: draft, name: Draft, description: "Write the abstract, then the full proposal, from the client's real material.", goal: "Abstract then full proposal drafted; submission stage abstract → build with body fields filled." }
|
|
1028
|
-
- { key: submit, name: Submit, description: "Finalize against the program deadline and submit the application.", goal: "Application submitted on time; submission stage = awaiting-results." }
|
|
1029
|
-
- { key: awaiting, name: Awaiting, description: "Track the decision and keep the client status current.", goal: "Submission status reflects where the decision stands (in-review / waiting-client / needs-document / blocked)." }
|
|
1030
|
-
- { key: awarded, name: Awarded, description: "Record the funder's decision and the awarded amount.", goal: "Submission outcome set (awarded / rejected / partial) with the awarded amount." }
|
|
1031
|
-
- { key: delivering, name: Delivering, description: "Work the program's tranche model — ship and record each tranche.", goal: "Tranche deliverables filled and trancheCompletion updated as milestones ship." }
|
|
1053
|
+
- { key: identify, name: Identify, category: planned, domain: operations, description: "Understand the project and which of the program's submission tracks fit — before any writing.", goal: "A clear project understanding and the fitting submission track; submission stage = scope." }
|
|
1054
|
+
- { key: draft, name: Draft, category: started, domain: operations, description: "Write the abstract, then the full proposal, from the client's real material.", goal: "Abstract then full proposal drafted; submission stage abstract → build with body fields filled." }
|
|
1055
|
+
- { key: submit, name: Submit, category: started, domain: operations, description: "Finalize against the program deadline and submit the application.", goal: "Application submitted on time; submission stage = awaiting-results." }
|
|
1056
|
+
- { key: awaiting, name: Awaiting, category: paused, domain: operations, description: "Track the decision and keep the client status current.", goal: "Submission status reflects where the decision stands (in-review / waiting-client / needs-document / blocked)." }
|
|
1057
|
+
- { key: awarded, name: Awarded, category: started, domain: operations, description: "Record the funder's decision and the awarded amount.", goal: "Submission outcome set (awarded / rejected / partial) with the awarded amount." }
|
|
1058
|
+
- { key: delivering, name: Delivering, category: started, domain: operations, description: "Work the program's tranche model — ship and record each tranche.", goal: "Tranche deliverables filled and trancheCompletion updated as milestones ship." }
|
|
1032
1059
|
executor: is-agent
|
|
1033
1060
|
grants:
|
|
1034
1061
|
- entity.create
|
|
@@ -1274,10 +1301,23 @@ bento:
|
|
|
1274
1301
|
w: 4
|
|
1275
1302
|
h: 6
|
|
1276
1303
|
integrations:
|
|
1277
|
-
- templateKey: stellar-grant-client
|
|
1278
1304
|
- templateKey: agency-skills
|
|
1279
1305
|
- templateKey: nango-google
|
|
1280
1306
|
- templateKey: discord-bot
|
|
1307
|
+
|
|
1308
|
+
# ── taskIntents — WHAT THIS WORKSPACE NEEDS TO FUNCTION ───────────────────
|
|
1309
|
+
# Closed vocabulary: `@synap-core/types/capability-intents` (pod migrations
|
|
1310
|
+
# 0283/0284). DERIVED from the declared intents of this template's own
|
|
1311
|
+
# `integrations` capability packs — not hand-guessed. Checked at authoring
|
|
1312
|
+
# time by `validateTemplate` (`task-intent-unknown`) and by
|
|
1313
|
+
# `src/task-intents.test.ts`.
|
|
1314
|
+
taskIntents:
|
|
1315
|
+
- send_message
|
|
1316
|
+
- search_external
|
|
1317
|
+
- list_records
|
|
1318
|
+
- schedule_event
|
|
1319
|
+
- manage_file
|
|
1320
|
+
- fetch_record
|
|
1281
1321
|
onboarding:
|
|
1282
1322
|
goal: Capture the agency's live grant pipeline — the funding rounds and their deadlines, the projects being advised, and the open submissions in flight — so the workspace mirrors the real book of work, not a generic template.
|
|
1283
1323
|
framing: "Act as a seasoned blockchain-grants advisor who has shepherded dozens of applications through programs like SCF, Optimism RetroPGF, and Arbitrum. Speak to how a submission actually wins: a crisp problem, a defensible reason the chain matters, evidence of traction, and milestones a reviewer can grade. Translate the founder's words into rounds, projects, and submissions on the pipeline."
|
package/src/hr.yaml
CHANGED
|
@@ -13,6 +13,12 @@ meta:
|
|
|
13
13
|
color: "#E8663D"
|
|
14
14
|
tags: [hr, people, hiring, team]
|
|
15
15
|
isPublic: true
|
|
16
|
+
# What this space PRODUCES (homes): the purpose word, then its kinds/roles.
|
|
17
|
+
intent:
|
|
18
|
+
label: Team
|
|
19
|
+
produces:
|
|
20
|
+
- profile: candidate
|
|
21
|
+
- profile: review
|
|
16
22
|
|
|
17
23
|
workspace:
|
|
18
24
|
name: People
|
|
@@ -20,7 +26,10 @@ workspace:
|
|
|
20
26
|
proposalId: hr-v1
|
|
21
27
|
subtype: hr
|
|
22
28
|
visibility: members
|
|
23
|
-
|
|
29
|
+
# A DOMAIN workspace that holds entities — NOT `operational`. `operational`
|
|
30
|
+
# marks an admin/system surface: `isDomainHomeWorkspace` refuses filing
|
|
31
|
+
# entities into it and excludes it from auto-placement (2026-09-25).
|
|
32
|
+
workspaceType: personal
|
|
24
33
|
capabilities:
|
|
25
34
|
- hr.team
|
|
26
35
|
- hr.hiring
|
|
@@ -153,6 +162,17 @@ profiles:
|
|
|
153
162
|
profileKind: role
|
|
154
163
|
applicableKinds:
|
|
155
164
|
- person
|
|
165
|
+
# The ONE lifecycle (work model L1): every option's category.
|
|
166
|
+
lifecycle:
|
|
167
|
+
property: stage
|
|
168
|
+
options:
|
|
169
|
+
- { key: applied, category: open }
|
|
170
|
+
- { key: screening, category: active }
|
|
171
|
+
- { key: interview, category: active }
|
|
172
|
+
- { key: offer, category: active }
|
|
173
|
+
- { key: hired, category: done }
|
|
174
|
+
- { key: rejected, category: lost }
|
|
175
|
+
- { key: withdrawn, category: lost }
|
|
156
176
|
properties:
|
|
157
177
|
- slug: stage
|
|
158
178
|
label: Stage
|
|
@@ -195,6 +215,16 @@ profiles:
|
|
|
195
215
|
icon: clipboard-check
|
|
196
216
|
color: violet
|
|
197
217
|
description: "A performance review within a company review cycle."
|
|
218
|
+
# The ONE lifecycle (work model L1): every option's category.
|
|
219
|
+
lifecycle:
|
|
220
|
+
property: status
|
|
221
|
+
options:
|
|
222
|
+
- { key: not-started, category: open }
|
|
223
|
+
- { key: self-review, category: active }
|
|
224
|
+
- { key: manager-review, category: active }
|
|
225
|
+
- { key: calibration, category: active }
|
|
226
|
+
- { key: shared, category: active }
|
|
227
|
+
- { key: complete, category: done }
|
|
198
228
|
properties:
|
|
199
229
|
- slug: cycle
|
|
200
230
|
label: Cycle
|
|
@@ -315,13 +345,13 @@ views:
|
|
|
315
345
|
]
|
|
316
346
|
- name: Hiring Pipeline
|
|
317
347
|
slug: hiring-pipeline
|
|
318
|
-
|
|
348
|
+
# The ONE board (work model L3, D3): columns ARE the candidate role's
|
|
349
|
+
# declared lifecycle (`stage`), moves go through the one mover.
|
|
350
|
+
type: pipeline
|
|
319
351
|
scopeProfileSlug: candidate
|
|
320
|
-
groupBy: stage
|
|
321
|
-
description: Candidates moving through the pipeline, by stage.
|
|
322
352
|
config:
|
|
323
|
-
|
|
324
|
-
|
|
353
|
+
profileSlug: candidate
|
|
354
|
+
description: Candidates moving through the pipeline, by stage.
|
|
325
355
|
- name: Open Roles
|
|
326
356
|
slug: open-roles
|
|
327
357
|
type: table
|
|
@@ -430,10 +460,12 @@ onboarding:
|
|
|
430
460
|
30/60/90 plan rather than ambiguity.
|
|
431
461
|
collect:
|
|
432
462
|
- profileSlug: team-member
|
|
463
|
+
min: 1
|
|
433
464
|
what: The people currently on the team, with their role, department, and status.
|
|
434
465
|
cardinality: several
|
|
435
466
|
keyFields: [role-title, department, status]
|
|
436
467
|
- profileSlug: role
|
|
468
|
+
min: 1
|
|
437
469
|
what: The positions you're hiring for right now — open reqs with their hiring bar.
|
|
438
470
|
cardinality: few
|
|
439
471
|
keyFields: [status, department, seniority]
|
|
@@ -442,6 +474,7 @@ onboarding:
|
|
|
442
474
|
cardinality: few
|
|
443
475
|
keyFields: [stage, source]
|
|
444
476
|
- profileSlug: review
|
|
477
|
+
min: 1
|
|
445
478
|
what: The current review cycle and how you run performance (cadence + rubric).
|
|
446
479
|
cardinality: one
|
|
447
480
|
keyFields: [cycle, status]
|
package/src/index.ts
CHANGED
|
@@ -50,13 +50,26 @@ export type {
|
|
|
50
50
|
TemplatePlaybookParam,
|
|
51
51
|
TemplateAutomation,
|
|
52
52
|
TemplateActionPlacement,
|
|
53
|
+
TemplateIntent,
|
|
54
|
+
TemplateSpacePackage,
|
|
55
|
+
TemplateSpacePackageCell,
|
|
53
56
|
} from "./types.js";
|
|
54
57
|
|
|
58
|
+
// A template's space package: its built frame modules (the base layer of the
|
|
59
|
+
// space's own experience, installed as `cell:<slug>:<key>`).
|
|
60
|
+
export { spacePackageCells } from "./space-packages.js";
|
|
61
|
+
export type {
|
|
62
|
+
BuiltSpacePackage,
|
|
63
|
+
BuiltSpacePackageCell,
|
|
64
|
+
SpacePackageCellWire,
|
|
65
|
+
} from "./space-packages.js";
|
|
66
|
+
|
|
55
67
|
// The dependency-kind vocabulary as a VALUE — so consumers (marketplace,
|
|
56
68
|
// onboarding, backend, hub zod, browser, CP zod) can `z.enum(PACKAGE_DEPENDENCY_KINDS)`
|
|
57
69
|
// / derive their type from it instead of hand-copying the list. Six mirrors
|
|
58
70
|
// exist today; this is the door that lets them stop being mirrors.
|
|
59
|
-
export { PACKAGE_DEPENDENCY_KINDS } from "./types.js";
|
|
71
|
+
export { PACKAGE_DEPENDENCY_KINDS, INTENT_LABEL_MAX, START_VIEWS_MAX, START_EXAMPLE_RANGE, START_STARTERS_RANGE } from "./types.js";
|
|
72
|
+
export type { TemplateStart } from "./types.js";
|
|
60
73
|
|
|
61
74
|
export {
|
|
62
75
|
WORKSPACE_TEMPLATES,
|
|
@@ -73,6 +86,9 @@ export {
|
|
|
73
86
|
assembleCatalog,
|
|
74
87
|
computeTemplateUpdates,
|
|
75
88
|
isHashVersion,
|
|
89
|
+
derivePlaybookItems,
|
|
90
|
+
TRACK_TEMPLATE_ITEM_KIND,
|
|
91
|
+
WORK_TEMPLATE_ITEM_KIND,
|
|
76
92
|
} from "./catalog.js";
|
|
77
93
|
export type {
|
|
78
94
|
MergeCatalogInput,
|
|
@@ -133,6 +149,11 @@ export {
|
|
|
133
149
|
SYSTEM_PROFILES,
|
|
134
150
|
REQUIRED_META_FIELDS,
|
|
135
151
|
REQUIRED_WORKSPACE_FIELDS,
|
|
152
|
+
lifecycleOptionWaitsProblems,
|
|
153
|
+
LIFECYCLE_OPTION_FIELDS,
|
|
154
|
+
LIFECYCLE_OPTION_WAITS_FIELDS,
|
|
155
|
+
LIFECYCLE_WAITS_ON,
|
|
156
|
+
LIFECYCLE_WAIT_KINDS,
|
|
136
157
|
} from "./validate.js";
|
|
137
158
|
export type {
|
|
138
159
|
ValidationError,
|
|
@@ -141,6 +162,18 @@ export type {
|
|
|
141
162
|
TemplateConverters,
|
|
142
163
|
} from "./validate.js";
|
|
143
164
|
|
|
165
|
+
// The ten base lifecycles as template-time presets (`lifecycle.adopts`) and the
|
|
166
|
+
// ONE compiler that turns them into the flat declaration the pod stores. The
|
|
167
|
+
// catalog loader (scripts/catalog-lib.mjs) compiles authored YAML through it.
|
|
168
|
+
export { BASE_LIFECYCLES, resolveLifecyclePresets } from "./lifecycle-presets.js";
|
|
169
|
+
export type {
|
|
170
|
+
BaseLifecycleName,
|
|
171
|
+
TemplateLifecycleAdoption,
|
|
172
|
+
TemplateLifecycleStepAdd,
|
|
173
|
+
LifecyclePresetProblem,
|
|
174
|
+
LifecyclePresetResolution,
|
|
175
|
+
} from "./lifecycle-presets.js";
|
|
176
|
+
|
|
144
177
|
// The pure, DB-free automation-flow node-contract validator. `validateTemplate`
|
|
145
178
|
// runs it over every `automations[].flow` so broken flows (unknown node type,
|
|
146
179
|
// dangling edge, cycle, typo'd channelType, verb-less capability node) fail at
|
|
@@ -165,6 +198,7 @@ export {
|
|
|
165
198
|
toPackageDefinition,
|
|
166
199
|
splitBentoBlocks,
|
|
167
200
|
normalizeTemplateLayout,
|
|
201
|
+
toAutomationWire,
|
|
168
202
|
} from "./define.js";
|
|
169
203
|
export type {
|
|
170
204
|
WorkspaceDefinitionInput,
|
|
@@ -173,4 +207,5 @@ export type {
|
|
|
173
207
|
SplitBentoBlocks,
|
|
174
208
|
BentoWidgetBlockWire,
|
|
175
209
|
BentoViewBlockWire,
|
|
210
|
+
PackageAutomationWire,
|
|
176
211
|
} from "./define.js";
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `meta.intent` — what a space PRODUCES (object-first homes H0).
|
|
3
|
+
*
|
|
4
|
+
* Pinned:
|
|
5
|
+
* - each `intent-*` rule fires on a minimal broken template and stays silent
|
|
6
|
+
* on the fixed one (label length, unknown profile, profile without a
|
|
7
|
+
* lifecycle, duplicate, shape);
|
|
8
|
+
* - a produced profile may come from the dependency closure, and its
|
|
9
|
+
* lifecycle may be declared there (a role foundation owns);
|
|
10
|
+
* - (the catalog header half lives in `schema/intent-header.test.ts`);
|
|
11
|
+
* - BOTH install doors carry it (top-level `intent` on both), driven through
|
|
12
|
+
* the real converters.
|
|
13
|
+
*/
|
|
14
|
+
import { describe, expect, it } from "vitest";
|
|
15
|
+
import { validateTemplate } from "./validate.js";
|
|
16
|
+
import { toPackageDefinition, toWorkspaceDefinition } from "./define.js";
|
|
17
|
+
import type { TemplateIntent, TemplateProfile, WorkspaceYaml } from "./types.js";
|
|
18
|
+
import { INTENT_LABEL_MAX } from "./types.js";
|
|
19
|
+
import { readYamlTemplates } from "./generate.mjs";
|
|
20
|
+
|
|
21
|
+
const lifecycled = (slug: string): TemplateProfile => ({
|
|
22
|
+
slug,
|
|
23
|
+
displayName: slug,
|
|
24
|
+
properties: [{ slug: "stage", label: "Stage", valueType: "string", inputType: "select", enumValues: ["a", "b"] }],
|
|
25
|
+
lifecycle: { property: "stage", options: [{ key: "a", category: "open" }, { key: "b", category: "done" }] },
|
|
26
|
+
} as TemplateProfile);
|
|
27
|
+
const plain = (slug: string): TemplateProfile => ({ slug, displayName: slug, properties: [] } as unknown as TemplateProfile);
|
|
28
|
+
|
|
29
|
+
const make = (slug: string, profiles: TemplateProfile[], intent?: TemplateIntent, deps: string[] = []): WorkspaceYaml =>
|
|
30
|
+
({
|
|
31
|
+
meta: { slug, name: slug, description: "d", icon: "box", color: "blue", ...(intent ? { intent } : {}) },
|
|
32
|
+
workspace: { name: slug, description: "d" },
|
|
33
|
+
profiles,
|
|
34
|
+
dependencies: deps.map((d) => ({ slug: d, relation: "require" as const })),
|
|
35
|
+
}) as WorkspaceYaml;
|
|
36
|
+
|
|
37
|
+
const base = make("base-dep", [lifecycled("role-x"), plain("bare-dep")]);
|
|
38
|
+
const resolveDep = (s: string) => (s === "base-dep" ? base : undefined);
|
|
39
|
+
const intentErrors = (t: WorkspaceYaml) =>
|
|
40
|
+
validateTemplate(t, { resolveDep }).errors.filter((e) => e.rule.startsWith("intent-"));
|
|
41
|
+
|
|
42
|
+
describe("meta.intent — validator rules", () => {
|
|
43
|
+
it("a well-formed intent (own kind + a dependency's role) passes", () => {
|
|
44
|
+
const t = make("t", [lifecycled("thing")], { label: "Product", produces: [{ profile: "thing" }, { profile: "role-x" }] }, ["base-dep"]);
|
|
45
|
+
expect(intentErrors(t)).toEqual([]);
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
it("a library (label only, or empty produces) passes", () => {
|
|
49
|
+
expect(intentErrors(make("t", [plain("x")], { label: "Library" }))).toEqual([]);
|
|
50
|
+
expect(intentErrors(make("t", [plain("x")], { label: "Library", produces: [] }))).toEqual([]);
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
it("intent-label: empty or longer than the max is refused", () => {
|
|
54
|
+
expect(intentErrors(make("t", [plain("x")], { label: "" })).map((e) => e.rule)).toEqual(["intent-label"]);
|
|
55
|
+
const long = "x".repeat(INTENT_LABEL_MAX + 1);
|
|
56
|
+
expect(intentErrors(make("t", [plain("x")], { label: long })).map((e) => e.rule)).toEqual(["intent-label"]);
|
|
57
|
+
expect(intentErrors(make("t", [plain("x")], { label: "x".repeat(INTENT_LABEL_MAX) }))).toEqual([]);
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
it("intent-profile-unknown: a profile neither own nor in the closure", () => {
|
|
61
|
+
const errs = intentErrors(make("t", [lifecycled("thing")], { label: "P", produces: [{ profile: "ghost" }] }));
|
|
62
|
+
expect(errs.map((e) => e.rule)).toEqual(["intent-profile-unknown"]);
|
|
63
|
+
expect(errs[0]!.message).toContain('"ghost"');
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
it("intent-profile-unknown: a dependency's profile is NOT reachable without the dependency", () => {
|
|
67
|
+
const errs = intentErrors(make("t", [lifecycled("thing")], { label: "P", produces: [{ profile: "role-x" }] }));
|
|
68
|
+
expect(errs.map((e) => e.rule)).toEqual(["intent-profile-unknown"]);
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
it("intent-no-lifecycle: names the produced profile that declares none", () => {
|
|
72
|
+
const own = intentErrors(make("t", [plain("thing")], { label: "P", produces: [{ profile: "thing" }] }));
|
|
73
|
+
expect(own.map((e) => e.rule)).toEqual(["intent-no-lifecycle"]);
|
|
74
|
+
expect(own[0]!.message).toContain('"thing"');
|
|
75
|
+
const dep = intentErrors(make("t", [lifecycled("thing")], { label: "P", produces: [{ profile: "bare-dep" }] }, ["base-dep"]));
|
|
76
|
+
expect(dep.map((e) => e.rule)).toEqual(["intent-no-lifecycle"]);
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
it("a re-declaration without the lifecycle still counts the dependency's declaration", () => {
|
|
80
|
+
const t = make("t", [plain("role-x")], { label: "P", produces: [{ profile: "role-x" }] }, ["base-dep"]);
|
|
81
|
+
expect(intentErrors(t)).toEqual([]);
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
it("intent-duplicate and intent-shape", () => {
|
|
85
|
+
const dup = intentErrors(make("t", [lifecycled("thing")], { label: "P", produces: [{ profile: "thing" }, { profile: "thing" }] }));
|
|
86
|
+
expect(dup.map((e) => e.rule)).toEqual(["intent-duplicate"]);
|
|
87
|
+
const shape = intentErrors(make("t", [lifecycled("thing")], { label: "P", produces: "thing" } as unknown as TemplateIntent));
|
|
88
|
+
expect(shape.map((e) => e.rule)).toEqual(["intent-shape"]);
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
it("intent-no-workspace: an overlay or a pack declares no intent", () => {
|
|
92
|
+
const overlay = make("t", [lifecycled("thing")], { label: "P" });
|
|
93
|
+
overlay.dependencies = [{ slug: "base-dep", relation: "compose" }];
|
|
94
|
+
expect(intentErrors(overlay).map((e) => e.rule)).toEqual(["intent-no-workspace"]);
|
|
95
|
+
const pack = make("t", [lifecycled("thing")], { label: "P" });
|
|
96
|
+
pack.meta.tags = ["suite"];
|
|
97
|
+
expect(intentErrors(pack).map((e) => e.rule)).toEqual(["intent-no-workspace"]);
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
it("an unresolvable dependency does not fabricate an unknown-profile error", () => {
|
|
101
|
+
const t = make("t", [lifecycled("thing")], { label: "P", produces: [{ profile: "elsewhere" }] }, ["not-in-corpus"]);
|
|
102
|
+
expect(intentErrors(t)).toEqual([]);
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
describe("meta.intent — both install doors carry it", () => {
|
|
107
|
+
const intent = { label: "Product", produces: [{ profile: "thing" }] };
|
|
108
|
+
const t = make("t", [lifecycled("thing")], intent);
|
|
109
|
+
|
|
110
|
+
it("package door: top-level intent, never in _meta (the CP rebuilds _meta on serve)", () => {
|
|
111
|
+
const def = toPackageDefinition(t);
|
|
112
|
+
expect(def.intent).toEqual(intent);
|
|
113
|
+
expect("intent" in def._meta).toBe(false);
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
it("workspace door: intent", () => {
|
|
117
|
+
expect(toWorkspaceDefinition(t).definition.intent).toEqual(intent);
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
it("no intent → no field on either door", () => {
|
|
121
|
+
const none = make("t", [lifecycled("thing")]);
|
|
122
|
+
expect("intent" in toPackageDefinition(none)).toBe(false);
|
|
123
|
+
expect(toWorkspaceDefinition(none).definition.intent).toBeUndefined();
|
|
124
|
+
});
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
describe("meta.intent — the catalog", () => {
|
|
128
|
+
const corpus = readYamlTemplates().map((t) => t.data as WorkspaceYaml);
|
|
129
|
+
const table = Object.fromEntries(
|
|
130
|
+
corpus
|
|
131
|
+
.filter((t) => t.meta.intent)
|
|
132
|
+
.map((t) => [t.meta.slug, [t.meta.intent!.label, ...(t.meta.intent!.produces ?? []).map((p) => p.profile)]])
|
|
133
|
+
);
|
|
134
|
+
|
|
135
|
+
it("the whole corpus validates with zero intent-* errors", () => {
|
|
136
|
+
const errs = corpus.flatMap((t) =>
|
|
137
|
+
validateTemplate(t, { corpus }).errors.filter((e) => e.rule.startsWith("intent-")).map((e) => `${t.meta.slug} ${e.rule}: ${e.message}`)
|
|
138
|
+
);
|
|
139
|
+
expect(errs).toEqual([]);
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
it("the founder's table (homes plan §1), in produces order", () => {
|
|
143
|
+
expect(table["builder-workspace"]).toEqual(["Product", "devplane_feature", "devplane_story", "ui-design"]);
|
|
144
|
+
// outreach-touch joined when CRM absorbed Outreach & Comms (founder decision 2026-10-23):
|
|
145
|
+
// the messages drafted for a person to send are part of the commercial job.
|
|
146
|
+
expect(table["crm"]).toEqual(["Sales", "lead", "client", "deal", "campaign", "outreach-touch"]);
|
|
147
|
+
expect(table["operations"]).toEqual(["Delivery", "engagement", "deliverable"]);
|
|
148
|
+
expect(table["content-os"]).toEqual(["Content", "post", "newsletter", "campaign"]);
|
|
149
|
+
expect(table["finance"]).toEqual(["Finance", "invoice", "expense"]);
|
|
150
|
+
expect(table["research-base"]).toEqual(["Research", "hypothesis", "finding"]);
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
it("libraries carry a label only; overlays and packs carry none", () => {
|
|
154
|
+
for (const slug of ["brand-library", "foundation", "ecosystem"]) expect(table[slug], slug).toHaveLength(1);
|
|
155
|
+
for (const t of corpus) {
|
|
156
|
+
const ownsNone =
|
|
157
|
+
(t.dependencies ?? []).some((d) => d.relation === "compose") || (t.meta.tags ?? []).includes("suite");
|
|
158
|
+
if (ownsNone) expect(t.meta.intent, t.meta.slug).toBeUndefined();
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
});
|
|
@@ -14,6 +14,9 @@ meta:
|
|
|
14
14
|
color: "#64748B"
|
|
15
15
|
tags: [operations, sops, vendors, workflows]
|
|
16
16
|
isPublic: true
|
|
17
|
+
# A LIBRARY: it produces nothing a home counts (homes).
|
|
18
|
+
intent:
|
|
19
|
+
label: Runbook
|
|
17
20
|
|
|
18
21
|
workspace:
|
|
19
22
|
name: Internal Runbook
|
|
@@ -26,7 +29,10 @@ workspace:
|
|
|
26
29
|
# operations), so it must own its own identity.
|
|
27
30
|
subtype: internal-runbook
|
|
28
31
|
visibility: members
|
|
29
|
-
|
|
32
|
+
# A DOMAIN workspace that holds entities — NOT `operational`. `operational`
|
|
33
|
+
# marks an admin/system surface: `isDomainHomeWorkspace` refuses filing
|
|
34
|
+
# entities into it and excludes it from auto-placement (2026-09-25).
|
|
35
|
+
workspaceType: personal
|
|
30
36
|
capabilities:
|
|
31
37
|
- operations.sops
|
|
32
38
|
- operations.vendors
|
|
@@ -90,6 +96,15 @@ profiles:
|
|
|
90
96
|
color: "#0EA5E9"
|
|
91
97
|
description: "A recurring business process — a repeatable flow with an owner, a cadence, and an input/output."
|
|
92
98
|
scope: WORKSPACE
|
|
99
|
+
# The ONE lifecycle (work model L1): every option's category.
|
|
100
|
+
lifecycle:
|
|
101
|
+
property: workflow-status
|
|
102
|
+
options:
|
|
103
|
+
- { key: Backlog, category: open }
|
|
104
|
+
- { key: Active, category: active }
|
|
105
|
+
- { key: Blocked, category: paused }
|
|
106
|
+
- { key: Optimizing, category: active }
|
|
107
|
+
- { key: Retired, category: lost }
|
|
93
108
|
properties:
|
|
94
109
|
- slug: workflow-status
|
|
95
110
|
label: Status
|
|
@@ -423,14 +438,17 @@ onboarding:
|
|
|
423
438
|
person's head.
|
|
424
439
|
collect:
|
|
425
440
|
- profileSlug: sop
|
|
441
|
+
min: 1
|
|
426
442
|
what: The core documented procedures / runbooks — the repeatable ways of doing key things.
|
|
427
443
|
cardinality: several
|
|
428
444
|
keyFields: [title, category, owner, sop-status]
|
|
429
445
|
- profileSlug: workflow
|
|
446
|
+
min: 1
|
|
430
447
|
what: The recurring processes that run the business, each with an owner and a cadence.
|
|
431
448
|
cardinality: several
|
|
432
449
|
keyFields: [title, workflow-status, frequency, owner]
|
|
433
450
|
- profileSlug: vendor
|
|
451
|
+
min: 1
|
|
434
452
|
what: The suppliers and service providers the company pays and depends on.
|
|
435
453
|
cardinality: few
|
|
436
454
|
keyFields: [title, vendor-category, monthly-cost, owner]
|