@elevasis/sdk 1.29.0 → 1.30.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/dist/cli.cjs +1608 -594
  2. package/dist/index.d.ts +87 -1
  3. package/dist/index.js +30 -25
  4. package/dist/node/index.d.ts +84 -1
  5. package/dist/test-utils/index.d.ts +84 -1
  6. package/dist/test-utils/index.js +242 -23
  7. package/dist/worker/index.js +1 -0
  8. package/package.json +2 -2
  9. package/reference/claude-config/rules/topbar-actions.md +70 -0
  10. package/reference/claude-config/skills/om/SKILL.md +18 -1
  11. package/reference/claude-config/sync-notes/2026-05-04-knowledge-bundle.md +83 -83
  12. package/reference/claude-config/sync-notes/2026-05-14-organization-model-ontology-refactor.md +45 -45
  13. package/reference/claude-config/sync-notes/2026-05-15-om-skill-rename-and-write-family.md +52 -52
  14. package/reference/claude-config/sync-notes/2026-05-17-sdk-boundary-consolidation.md +33 -33
  15. package/reference/claude-config/sync-notes/2026-05-20-om-define-helpers.md +32 -32
  16. package/reference/claude-config/sync-notes/2026-05-22-access-model-and-right-panel.md +43 -43
  17. package/reference/claude-config/sync-notes/2026-05-22-lead-gen-tenant-config.md +40 -40
  18. package/reference/claude-config/sync-notes/2026-05-22-org-model-multi-file-split.md +61 -61
  19. package/reference/claude-config/sync-notes/2026-05-23-branding-names-to-identity.md +49 -49
  20. package/reference/claude-config/sync-notes/2026-05-23-lead-gen-manage-access.md +31 -31
  21. package/reference/claude-config/sync-notes/2026-05-23-om-deployment-drift-detection.md +42 -42
  22. package/reference/claude-config/sync-notes/2026-05-23-om-full-model-deploy-contract.md +33 -33
  23. package/reference/claude-config/sync-notes/2026-05-23-ui-sdk-package-fixes.md +37 -37
  24. package/reference/claude-config/sync-notes/2026-05-24-platform-invite-router-core-baseline.md +28 -28
  25. package/reference/claude-config/sync-notes/2026-05-24-system-interface-readiness.md +43 -43
  26. package/reference/claude-config/sync-notes/2026-05-25-invitation-login-loader.md +26 -0
  27. package/reference/claude-config/sync-notes/2026-05-25-om-topbar-requests.md +33 -0
  28. package/reference/claude-config/sync-notes/2026-05-25-system-interface-profile-registry-and-substrate.md +35 -0
  29. package/reference/claude-config/sync-notes/2026-05-25-tenant-om-scaffold-cli.md +49 -0
  30. package/reference/claude-config/sync-notes/2026-05-25-vibe-operate-intent.md +47 -0
  31. package/reference/examples/organization-model.ts +18 -0
  32. package/reference/rules/organization-model.md +4 -1
  33. package/reference/rules/organization-os.md +7 -1
  34. package/reference/rules/ui.md +207 -207
  35. package/reference/rules/vibe.md +52 -18
  36. package/reference/scaffold/index.mdx +9 -7
  37. package/reference/scaffold/operations/scaffold-maintenance.md +14 -4
  38. package/reference/scaffold/reference/contracts.md +423 -338
  39. package/reference/scaffold/reference/glossary.md +14 -2
  40. package/reference/scaffold/reference/system-interface-capabilities.md +50 -0
  41. /package/reference/claude-config/skills/deploy/{skill.md → SKILL.md} +0 -0
@@ -6886,6 +6886,7 @@ var ORGANIZATION_MODEL_ICON_TOKENS = [
6886
6886
  "view",
6887
6887
  "launch",
6888
6888
  "message",
6889
+ "message-plus",
6889
6890
  "escalate",
6890
6891
  "promote",
6891
6892
  "submit",
@@ -6923,7 +6924,7 @@ var LabelSchema = z.string().trim().min(1).max(120);
6923
6924
  var DescriptionSchema = z.string().trim().min(1).max(2e3);
6924
6925
  var ColorTokenSchema = z.string().trim().min(1).max(50);
6925
6926
  var IconNameSchema = OrganizationModelIconTokenSchema;
6926
- z.string().trim().startsWith("/").max(300);
6927
+ var PathSchema = z.string().trim().startsWith("/").max(300);
6927
6928
  var ReferenceIdsSchema = z.array(ModelIdSchema).default([]);
6928
6929
  var DisplayMetadataSchema = z.object({
6929
6930
  label: LabelSchema,
@@ -6995,6 +6996,89 @@ function listAllSystems(model) {
6995
6996
  return results;
6996
6997
  }
6997
6998
 
6999
+ // ../core/src/organization-model/domains/entities.ts
7000
+ var EntityIdSchema = ModelIdSchema;
7001
+ var EntityLinkKindSchema = z.enum(["belongs-to", "has-many", "has-one", "many-to-many"]).meta({ label: "Link kind" });
7002
+ var EntityLinkSchema = z.object({
7003
+ toEntity: EntityIdSchema.meta({ ref: "entity" }),
7004
+ kind: EntityLinkKindSchema,
7005
+ via: z.string().trim().min(1).max(255).optional(),
7006
+ label: LabelSchema.optional()
7007
+ });
7008
+ var EntitySchema = z.object({
7009
+ id: EntityIdSchema,
7010
+ /** Domain-map iteration order. Convention: multiples of 10 (10, 20, 30, ...) to allow easy insertion. */
7011
+ order: z.number(),
7012
+ label: LabelSchema,
7013
+ description: DescriptionSchema.optional(),
7014
+ ownedBySystemId: ModelIdSchema.meta({ ref: "system" }),
7015
+ table: z.string().trim().min(1).max(255).optional(),
7016
+ rowSchema: ModelIdSchema.optional(),
7017
+ stateCatalogId: ModelIdSchema.optional(),
7018
+ links: z.array(EntityLinkSchema).optional()
7019
+ });
7020
+ z.record(z.string(), EntitySchema).refine((record) => Object.entries(record).every(([key, entry]) => entry.id === key), {
7021
+ message: "Each entity entry id must match its map key"
7022
+ }).default({});
7023
+
7024
+ // ../core/src/organization-model/domains/actions.ts
7025
+ var ActionResourceIdSchema = z.string().trim().min(1).max(255).regex(/^[A-Za-z0-9]+(?:[-._][A-Za-z0-9]+)*$/, "Resource IDs must use letters, numbers, -, _, or . separators");
7026
+ z.enum(["slash-command", "mcp-tool", "api-endpoint", "script-execution"]).meta({ label: "Invocation kind" });
7027
+ var ActionIdSchema = ModelIdSchema;
7028
+ var ActionScopeSchema = z.union([
7029
+ z.literal("global"),
7030
+ z.object({
7031
+ domain: ModelIdSchema
7032
+ })
7033
+ ]);
7034
+ var ActionRefSchema = z.object({
7035
+ actionId: ActionIdSchema.meta({ ref: "action" }),
7036
+ intent: z.enum(["exposes", "consumes"]).meta({ label: "Intent" })
7037
+ });
7038
+ var SlashCommandInvocationSchema = z.object({
7039
+ kind: z.literal("slash-command"),
7040
+ command: z.string().trim().min(1).max(200).regex(/^\/[^\s].*$/, "Slash commands must start with /"),
7041
+ toolFactory: ModelIdSchema.optional()
7042
+ });
7043
+ var McpToolInvocationSchema = z.object({
7044
+ kind: z.literal("mcp-tool"),
7045
+ server: ModelIdSchema,
7046
+ name: ModelIdSchema
7047
+ });
7048
+ var ApiEndpointInvocationSchema = z.object({
7049
+ kind: z.literal("api-endpoint"),
7050
+ method: z.enum(["GET", "POST", "PATCH", "DELETE"]).meta({ label: "HTTP method" }),
7051
+ path: z.string().trim().startsWith("/").max(500),
7052
+ requestSchema: ModelIdSchema.optional(),
7053
+ responseSchema: ModelIdSchema.optional()
7054
+ });
7055
+ var ScriptExecutionInvocationSchema = z.object({
7056
+ kind: z.literal("script-execution"),
7057
+ resourceId: ActionResourceIdSchema
7058
+ });
7059
+ var ActionInvocationSchema = z.discriminatedUnion("kind", [
7060
+ SlashCommandInvocationSchema,
7061
+ McpToolInvocationSchema,
7062
+ ApiEndpointInvocationSchema,
7063
+ ScriptExecutionInvocationSchema
7064
+ ]);
7065
+ var ActionSchema = z.object({
7066
+ id: ActionIdSchema,
7067
+ /** Domain-map iteration order. Convention: multiples of 10 (10, 20, 30, ...) to allow easy insertion. */
7068
+ order: z.number(),
7069
+ label: LabelSchema,
7070
+ description: DescriptionSchema.optional(),
7071
+ scope: ActionScopeSchema.default("global"),
7072
+ resourceId: ActionResourceIdSchema.optional(),
7073
+ affects: z.array(EntityIdSchema.meta({ ref: "entity" })).optional(),
7074
+ invocations: z.array(ActionInvocationSchema).default([]),
7075
+ knowledge: z.array(ModelIdSchema.meta({ ref: "knowledge" })).default([]).optional(),
7076
+ lifecycle: z.enum(["draft", "beta", "active", "deprecated", "archived"]).meta({ label: "Lifecycle", color: "teal" }).default("active")
7077
+ });
7078
+ z.record(z.string(), ActionSchema).refine((record) => Object.entries(record).every(([key, entry]) => entry.id === key), {
7079
+ message: "Each action entry id must match its map key"
7080
+ }).default({});
7081
+
6998
7082
  // ../core/src/organization-model/domains/prospecting.ts
6999
7083
  DisplayMetadataSchema.extend({
7000
7084
  id: ModelIdSchema,
@@ -8316,7 +8400,7 @@ var OntologyGroupSchema = OntologyRecordBaseSchema.extend({
8316
8400
  var OntologySurfaceTypeSchema = OntologyRecordBaseSchema.extend({
8317
8401
  route: z.string().trim().min(1).max(500).optional()
8318
8402
  });
8319
- z.object({
8403
+ var OntologyScopeSchema = z.object({
8320
8404
  objectTypes: z.record(OntologyIdSchema, OntologyObjectTypeSchema).default({}).optional(),
8321
8405
  linkTypes: z.record(OntologyIdSchema, OntologyLinkTypeSchema).default({}).optional(),
8322
8406
  actionTypes: z.record(OntologyIdSchema, OntologyActionTypeSchema).default({}).optional(),
@@ -8549,6 +8633,152 @@ function compileOrganizationOntology(model) {
8549
8633
  addLegacyActionProjections(ontology, diagnostics, sourcesById, model.actions ?? {}, model.entities ?? {});
8550
8634
  return { ontology: sortResolvedOntologyIndex(ontology), diagnostics };
8551
8635
  }
8636
+ var SystemKindSchema = z.enum(["product", "operational", "platform", "diagnostic"]).meta({ label: "System kind", color: "blue" });
8637
+ var SystemLifecycleSchema = z.enum(["draft", "beta", "active", "deprecated", "archived"]).meta({ label: "Lifecycle", color: "teal" });
8638
+ var SystemStatusSchema = z.enum(["active", "deprecated", "archived"]).meta({ label: "Status", color: "teal" });
8639
+ var SystemIdSchema = ModelIdSchema;
8640
+ var SystemPathSchema = z.string().trim().min(1).regex(
8641
+ /^[a-z0-9][a-z0-9-]*(?:\.[a-z0-9][a-z0-9-]*)*$/,
8642
+ 'must be a dotted lowercase path (e.g. "sales.lead-gen" or "sales.crm")'
8643
+ );
8644
+ var UiPositionSchema = z.enum(["sidebar-primary", "sidebar-bottom"]).meta({ label: "UI position" });
8645
+ z.string().trim().min(1).max(200).regex(
8646
+ /^[a-z][a-z-]*:([a-z0-9-]+)(\.[a-z0-9-]+)*(:[a-z0-9.-]+)*$/,
8647
+ "Node references must use kind:dotted-path (e.g. system:sales.crm or resource:lead-gen.company.qualify)"
8648
+ );
8649
+ var SystemUiSchema = z.object({
8650
+ path: PathSchema,
8651
+ surfaces: ReferenceIdsSchema,
8652
+ icon: IconNameSchema.optional(),
8653
+ order: z.number().int().optional()
8654
+ });
8655
+ var SystemInterfaceKeySchema = ModelIdSchema;
8656
+ var SystemInterfaceLifecycleSchema = z.enum(["draft", "active", "disabled", "deprecated", "archived"]).meta({ label: "System interface lifecycle", color: "teal" });
8657
+ var SYSTEM_INTERFACE_PROFILES = [
8658
+ {
8659
+ systemPath: "sales.lead-gen",
8660
+ interfaceKey: "api",
8661
+ readinessProfile: "sales.lead-gen.api"
8662
+ },
8663
+ {
8664
+ systemPath: "sales.crm",
8665
+ interfaceKey: "api",
8666
+ readinessProfile: "sales.crm.api"
8667
+ },
8668
+ {
8669
+ systemPath: "sales.lead-gen",
8670
+ interfaceKey: "crm-handoff",
8671
+ readinessProfile: "sales.lead-gen.crm-handoff"
8672
+ }
8673
+ ];
8674
+ var SYSTEM_INTERFACE_READINESS_PROFILES = SYSTEM_INTERFACE_PROFILES.map(
8675
+ (profile) => profile.readinessProfile
8676
+ );
8677
+ var SystemInterfaceReadinessProfileSchema = z.enum(SYSTEM_INTERFACE_READINESS_PROFILES);
8678
+ var SystemInterfaceResourceScopeSchema = z.array(ModelIdSchema).default([]);
8679
+ var SystemApiInterfaceSchema = z.object({
8680
+ lifecycle: SystemInterfaceLifecycleSchema.default("active"),
8681
+ readinessProfile: SystemInterfaceReadinessProfileSchema.optional(),
8682
+ /**
8683
+ * Resource ids that participate in this API interface. This scopes readiness
8684
+ * derivation without duplicating authored required/provided contract refs.
8685
+ */
8686
+ resourceIds: SystemInterfaceResourceScopeSchema.optional()
8687
+ }).strict();
8688
+ z.object({
8689
+ systemPath: SystemPathSchema,
8690
+ interfaceKey: SystemInterfaceKeySchema
8691
+ }).strict();
8692
+ var JsonValueSchema = z.lazy(
8693
+ () => z.union([
8694
+ z.string(),
8695
+ z.number(),
8696
+ z.boolean(),
8697
+ z.null(),
8698
+ z.array(JsonValueSchema),
8699
+ z.record(z.string(), JsonValueSchema)
8700
+ ])
8701
+ );
8702
+ var SystemConfigSchema = z.record(z.string().trim().min(1).max(200), JsonValueSchema).default({}).optional();
8703
+ var SystemEntrySchema = z.object({
8704
+ /** Stable tenant-defined system id (e.g. "sys.lead-gen" or "sales.crm"). */
8705
+ id: SystemIdSchema,
8706
+ /** Human-readable system label shown in UI, governance, and operations surfaces. */
8707
+ label: LabelSchema.optional(),
8708
+ /** @deprecated Use label. Accepted for pre-consolidation System declarations. */
8709
+ title: LabelSchema.optional(),
8710
+ /** One-paragraph purpose statement for the bounded context. */
8711
+ description: DescriptionSchema.optional(),
8712
+ /** Closed system shape enum; catalog values remain tenant-defined. */
8713
+ kind: SystemKindSchema.optional(),
8714
+ /** Optional self-reference for System hierarchy. */
8715
+ parentSystemId: SystemIdSchema.optional(),
8716
+ /** Optional UI presence. Systems without UI omit this. */
8717
+ ui: SystemUiSchema.optional(),
8718
+ /** Canonical lifecycle state. Replaces Feature.enabled/devOnly and System.status. */
8719
+ lifecycle: SystemLifecycleSchema.optional(),
8720
+ /** Optional role responsible for this system. */
8721
+ responsibleRoleId: ModelIdSchema.meta({ ref: "role" }).optional(),
8722
+ /** Optional knowledge nodes that govern this system. */
8723
+ governedByKnowledge: z.array(ModelIdSchema.meta({ ref: "knowledge" })).default([]).optional(),
8724
+ /** Optional actions this system exposes or consumes. */
8725
+ actions: z.array(ActionRefSchema).optional(),
8726
+ /** Optional operational policies that apply to this system. */
8727
+ policies: z.array(ModelIdSchema.meta({ ref: "policy" })).default([]).optional(),
8728
+ /** Optional goals this system contributes to. */
8729
+ drivesGoals: z.array(ModelIdSchema.meta({ ref: "goal" })).default([]).optional(),
8730
+ /** Thin API runtime-boundary marker. Readiness is derived from scoped resources and topology. */
8731
+ apiInterface: SystemApiInterfaceSchema.optional(),
8732
+ /** @deprecated Use lifecycle. Accepted for one publish cycle. */
8733
+ status: SystemStatusSchema.optional(),
8734
+ /** @deprecated Use ui.path. Kept for one-cycle Feature compatibility. */
8735
+ path: PathSchema.optional(),
8736
+ /** @deprecated Use ui.icon. Kept for one-cycle Feature compatibility. */
8737
+ icon: IconNameSchema.optional(),
8738
+ /** @deprecated Feature color token, retained for one-cycle compatibility. */
8739
+ color: ColorTokenSchema.optional(),
8740
+ /** @deprecated UI placement hint, retained for one-cycle compatibility. */
8741
+ uiPosition: UiPositionSchema.optional(),
8742
+ /** @deprecated Use lifecycle. */
8743
+ enabled: z.boolean().optional(),
8744
+ /** @deprecated Use lifecycle: "beta". */
8745
+ devOnly: z.boolean().optional(),
8746
+ requiresAdmin: z.boolean().optional(),
8747
+ /** Domain-map iteration order. Convention: multiples of 10 (10, 20, 30, ...) to allow easy insertion. */
8748
+ order: z.number(),
8749
+ /**
8750
+ * System-local JSON settings and defaults. Strongly typed OM fields,
8751
+ * secrets, credentials, and runtime state stay outside this bucket.
8752
+ */
8753
+ config: SystemConfigSchema,
8754
+ /**
8755
+ * System-owned ontology declarations. `systems` is now the canonical child
8756
+ * key; this scope holds the object, action, catalog, link, event, and
8757
+ * shared contract records owned by this system.
8758
+ */
8759
+ ontology: OntologyScopeSchema.optional(),
8760
+ /**
8761
+ * Recursive child systems, authored via nesting (per L11).
8762
+ * The key is the local system id; the full path is computed by joining
8763
+ * ancestor keys with `.` (e.g. parent key `'sales'` + child key `'crm'` → `'sales.crm'`).
8764
+ * Per Phase 4: `id` and `parentSystemId` fields will be removed in favour of
8765
+ * position-derived paths. Both still exist on this schema for backward compat.
8766
+ */
8767
+ systems: z.lazy(() => z.record(z.string().trim().min(1).max(100), SystemEntrySchema)).optional(),
8768
+ /** @deprecated Use systems. Accepted as a compatibility alias during the ontology bridge. */
8769
+ subsystems: z.lazy(() => z.record(z.string().trim().min(1).max(100), SystemEntrySchema)).optional()
8770
+ }).strict().refine((system) => system.label !== void 0 || system.title !== void 0, {
8771
+ path: ["label"],
8772
+ message: "System must provide label or title"
8773
+ }).transform((system) => {
8774
+ const normalizedSystem = system.systems !== void 0 && system.subsystems === void 0 ? { ...system, subsystems: system.systems } : system;
8775
+ if (normalizedSystem.status === void 0) return normalizedSystem;
8776
+ console.warn("[organization-model] System.status is deprecated; use System.lifecycle instead.");
8777
+ return normalizedSystem.lifecycle === void 0 ? { ...normalizedSystem, lifecycle: normalizedSystem.status } : normalizedSystem;
8778
+ });
8779
+ z.record(z.string(), SystemEntrySchema).refine((record) => Object.entries(record).every(([key, entry]) => entry.id === key), {
8780
+ message: "Each system entry id must match its map key"
8781
+ }).default({});
8552
8782
 
8553
8783
  // ../core/src/organization-model/migration-helpers.ts
8554
8784
  function catalogRecords(model) {
@@ -8626,21 +8856,12 @@ z.object({
8626
8856
  });
8627
8857
 
8628
8858
  // ../core/src/business/acquisition/ontology-validation.ts
8629
- var LEAD_GEN_API_INTERFACE = {
8630
- interfaceKey: "api",
8631
- readinessProfile: "sales.lead-gen.api"
8632
- };
8633
- var CRM_API_INTERFACE = {
8634
- systemPath: "sales.crm",
8635
- interfaceKey: "api",
8636
- readinessProfile: "sales.crm.api"
8637
- };
8638
- var LEAD_GEN_CRM_HANDOFF_INTERFACE = {
8639
- systemPath: "sales.lead-gen",
8640
- interfaceKey: "crm-handoff",
8641
- readinessProfile: "sales.lead-gen.crm-handoff"
8642
- };
8859
+ var LEAD_GEN_API_INTERFACE = SYSTEM_INTERFACE_PROFILES[0];
8860
+ var CRM_API_INTERFACE = SYSTEM_INTERFACE_PROFILES[1];
8861
+ var LEAD_GEN_CRM_HANDOFF_INTERFACE = SYSTEM_INTERFACE_PROFILES[2];
8862
+ LEAD_GEN_API_INTERFACE.readinessProfile;
8643
8863
  CRM_API_INTERFACE.readinessProfile;
8864
+ LEAD_GEN_CRM_HANDOFF_INTERFACE.readinessProfile;
8644
8865
  var LEAD_GEN_LIST_OBJECT_ONTOLOGY_ID = formatOntologyId({
8645
8866
  scope: "sales.lead-gen",
8646
8867
  kind: "object",
@@ -8718,6 +8939,9 @@ function profileForInterface(systemPath, interfaceKey, readinessProfile) {
8718
8939
  function readinessMarkerPath(context) {
8719
8940
  return context.interfaceKey === "api" ? `systems.${context.systemPath}.apiInterface` : `systems.${context.systemPath}.derivedCrmHandoffReadiness`;
8720
8941
  }
8942
+ function formatSupportedReadinessProfiles() {
8943
+ return SYSTEM_INTERFACE_READINESS_PROFILES.map((profile) => `"${profile}"`).join(", ");
8944
+ }
8721
8945
  function getActiveScopedResources(model, resourceIds, issues, context) {
8722
8946
  const resources = [];
8723
8947
  for (const [index2, resourceId] of resourceIds.entries()) {
@@ -8997,18 +9221,13 @@ function computeInterfaceReadiness(model, request) {
8997
9221
  { path: `${readinessMarkerPath(request)}.lifecycle` }
8998
9222
  );
8999
9223
  }
9000
- const supportedProfiles = [
9001
- LEAD_GEN_API_INTERFACE.readinessProfile,
9002
- CRM_API_INTERFACE.readinessProfile,
9003
- LEAD_GEN_CRM_HANDOFF_INTERFACE.readinessProfile
9004
- ];
9005
- const supportedProfile = readinessProfile !== void 0 && supportedProfiles.some((profile) => profile === readinessProfile);
9224
+ const supportedProfile = readinessProfile !== void 0 && SYSTEM_INTERFACE_PROFILES.some((profile) => profile.readinessProfile === readinessProfile);
9006
9225
  if (!supportedProfile) {
9007
9226
  addReadinessIssue(
9008
9227
  issues,
9009
9228
  "SYSTEM_INTERFACE_INVALID",
9010
9229
  "unknown-readiness-profile",
9011
- `System Interface "${formatInterfaceIdentity(request.systemPath, request.interfaceKey)}" references unknown readiness profile "${readinessProfile}".`,
9230
+ `System Interface "${formatInterfaceIdentity(request.systemPath, request.interfaceKey)}" references unknown readiness profile "${readinessProfile}". Supported profiles: ${formatSupportedReadinessProfiles()}. Custom Systems should not declare apiInterface; route custom behavior through workflows/operations plus ontology, resources, and topology.`,
9012
9231
  { path: `${readinessMarkerPath(request)}.readinessProfile`, ref: readinessProfile }
9013
9232
  );
9014
9233
  return {
@@ -4978,6 +4978,7 @@ var ORGANIZATION_MODEL_ICON_TOKENS = [
4978
4978
  "view",
4979
4979
  "launch",
4980
4980
  "message",
4981
+ "message-plus",
4981
4982
  "escalate",
4982
4983
  "promote",
4983
4984
  "submit",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elevasis/sdk",
3
- "version": "1.29.0",
3
+ "version": "1.30.0",
4
4
  "description": "SDK for building Elevasis organization resources",
5
5
  "type": "module",
6
6
  "bin": {
@@ -58,7 +58,7 @@
58
58
  "tsup": "^8.0.0",
59
59
  "typescript": "5.9.2",
60
60
  "zod": "^4.1.0",
61
- "@repo/core": "0.36.0",
61
+ "@repo/core": "0.38.0",
62
62
  "@repo/eslint-config": "0.0.0",
63
63
  "@repo/typescript-config": "0.0.0"
64
64
  },
@@ -0,0 +1,70 @@
1
+ ---
2
+ description: OM-declared topbar actions — navigation.topbar field and TOPBAR_ACTION_MANIFESTS registry pattern
3
+ paths:
4
+ - ui/src/lib/components/AppTopbar*
5
+ - ui/src/routes/__root*
6
+ - core/config/organization-model/**
7
+ ---
8
+
9
+ # Topbar Actions (Template Mirror Discipline — Tier 1 Note)
10
+
11
+ > **Scope:** This note documents substrate that has landed in the monorepo but is not yet published
12
+ > to `@elevasis/sdk/reference/rules/`. It will be superseded by the bundled rule once the
13
+ > `@elevasis/ui` minor that carries the topbar substrate ships. Until then, use this file.
14
+
15
+ ## navigation.topbar OM Field
16
+
17
+ The Organization Model now has a `navigation.topbar` region for declaring topbar action items.
18
+ Each entry is a distinct node type — OM owns data and visibility; a registry binds behavior.
19
+
20
+ ```ts
21
+ // core/config/organization-model.ts (navigation section)
22
+ navigation: {
23
+ topbar: {
24
+ request: {
25
+ id: 'request',
26
+ label: 'Request a feature or report an issue',
27
+ tooltip: 'Request a feature or report an issue',
28
+ icon: 'message-plus',
29
+ order: 10,
30
+ enabled: true
31
+ }
32
+ }
33
+ }
34
+ ```
35
+
36
+ Topbar items are toggled via `/org-os manage` exactly like sidebar surfaces. The `surfaceType`
37
+ enum (`page | dashboard | list | detail | graph | settings`) does NOT apply to topbar items —
38
+ they are a separate node type, not surfaces.
39
+
40
+ ## TOPBAR_ACTION_MANIFESTS Registry
41
+
42
+ Behavior for each `navigation.topbar` key is bound through a manifest registry in
43
+ `@elevasis/ui`. Each manifest maps a key to a render function:
44
+
45
+ ```ts
46
+ // Registered in packages/ui/src/features/registry/manifests.ts
47
+ TOPBAR_ACTION_MANIFESTS = {
48
+ request: requestTopbarActionManifest
49
+ }
50
+ ```
51
+
52
+ The `requestTopbarActionManifest` renders `<RequestActionIcon />` from
53
+ `@elevasis/ui/features/monitoring/requests`. It owns its own disclosure state and modal —
54
+ no wiring needed at the call site.
55
+
56
+ ## Template Authoring (Tier 2 — Post-Publish)
57
+
58
+ Declaring `navigation.topbar.request` in the template OM and rendering `<TopbarActions />`
59
+ in `AppTopbar` is **Tier 2 post-publish authoring** — it runs after the `@elevasis/ui` minor
60
+ bump lands in `external/_template`. Do NOT edit `core/config/organization-model/**` for this
61
+ until the publish + baseline bump step completes.
62
+
63
+ The requests-page `RequestButton` (entry point C) is a CC-level app-local addition in the
64
+ platform `apps/command-center` routes. Template projects add their own equivalent in
65
+ `ui/src/routes/monitoring/requests.index.tsx` after the surface is present in their navigation.
66
+
67
+ ## Related Rules
68
+
69
+ - `node_modules/@elevasis/sdk/reference/rules/organization-model.md` — OM schema and authoring ceremony
70
+ - `node_modules/@elevasis/sdk/reference/rules/organization-os.md` — `/org-os manage` toggle surface
@@ -47,6 +47,8 @@ metadata:
47
47
  - knowledge graph
48
48
  - knowledge browser
49
49
  - ontology
50
+ - apiInterface
51
+ - interface readiness
50
52
  - by-ontology
51
53
  - list my roles
52
54
  - what is our
@@ -95,7 +97,7 @@ primitive. When two buckets fit, prefer the higher one (more specific → more g
95
97
  | --- | ------------------------------ | --------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- |
96
98
  | 1 | Named knowledge/role/policy id | User names `knowledge.<id>`, `role.<id>`, `policy.<id>` directly | `om:cat <id>` for body, `om:describe <id>` for neighborhood |
97
99
  | 2 | Named system | User names a system path (`sales.crm`, `sales.lead-gen`) | `om:describe <id>` |
98
- | 3 | Named ontology id | Id contains `:object/`, `:action/`, `:event/`, `:catalog/`, `:link/`, `:surface/` | `om:describe <id>` (or `om:ls /by-ontology/<id> --ids-only` then `om:cat` each) |
100
+ | 3 | Named ontology id | Id contains `:object/`, `:action/`, `:event/`, `:catalog/`, `:interface/`, `:link/`, `:surface/` | `om:describe <id>` (or `om:ls /by-ontology/<id> --ids-only` then `om:cat` each) |
99
101
  | 4 | Kind keyword | "playbooks", "strategies", "all references", "list policies" | `om:ls /by-kind/<kind> --ids-only` then `om:cat` each |
100
102
  | 5 | Free-text discovery | Anything else ("lead gen", "outreach", "what governs X?") | `om:search "<query>"` then drill into top hit with `om:describe` |
101
103
 
@@ -198,6 +200,7 @@ what adjacent context may matter:
198
200
  | What resources belong to a System? | the id-keyed `organizationModel.resources` map and `getResourcesForSystem(model, systemPath)` | use `{ includeDescendants: true }` only for parent-scope rollups |
199
201
  | What can a System do? | system action refs and the actions domain | `action.resourceId`, invocation metadata, affected entities, policies |
200
202
  | What data does it own? | entities domain | owning System refs, state catalogs, entity links, emitted/projected events |
203
+ | Is a platform API interface ready? | the System's `apiInterface` marker and `node_modules/@elevasis/sdk/reference/scaffold/reference/system-interface-capabilities.md` | matching convention-locked System path, cataloged `readinessProfile`, derived resource ontology bindings, and scoped topology grants |
201
204
  | What UI surface exposes it? | `navigation.sidebar` plus `SystemModule` manifests | route files, surface targets, route-prefix modules, guards |
202
205
  | What knowledge applies? | `om:ls /by-system/<id>` plus graph edges | `om:cat`, `om:graph`, `/graph/<id>/governed-by` |
203
206
 
@@ -207,6 +210,20 @@ follow the relationship that matches the work. Prefer structured helpers from
207
210
 
208
211
  ---
209
212
 
213
+ ## API Interface Readiness
214
+
215
+ `system.apiInterface` is adopt-only in tenant projects. It declares intent to adopt a platform-provided API capability from the installed `@elevasis/core` / `@elevasis/sdk` version; it is not a tenant extension point.
216
+
217
+ Use only readiness profiles listed in `node_modules/@elevasis/sdk/reference/scaffold/reference/system-interface-capabilities.md`. The profile also fixes the required System path, such as `sales.lead-gen` or `sales.crm`. Do not invent a profile, and do not repoint a cataloged profile to a custom System path.
218
+
219
+ Readiness is derived, not hand-authored. After the marker is present, the validator checks ontology object/catalog types, scoped resources and their `resource.ontology` bindings, and any required scoped topology `uses` grants. Lead-gen to CRM handoff is represented as a scoped topology relationship under the cross-System boundary invariant, not as an authored bridge object.
220
+
221
+ Custom Systems should not carry `apiInterface`. Build custom behavior through `System.ontology`, `System.config`, resources, catalogs, topology, navigation, and workflows/operations. Runtime business logic belongs in workflows and agents registered by `operations/src/index.ts`; the tenant project does not add platform API routes.
222
+
223
+ Do not confuse ontology `interface` records with `system.apiInterface`. Ontology ids such as `<system>:interface/<local-id>` describe semantic model records under `System.ontology`; `system.apiInterface` is a flat System-level marker for closed platform API readiness.
224
+
225
+ ---
226
+
210
227
  ## Shared Layering Preview
211
228
 
212
229
  When opening a domain that uses a closed stage, status, or catalog vocabulary -- especially
@@ -1,83 +1,83 @@
1
- # Knowledge Bundle Ship-Train
2
-
3
- ## Why this note exists
4
-
5
- The Knowledge Map (Browser, CLI, skill, icons, external parity) is being shipped as a coordinated bundle. The Organization Model now treats `knowledge` as a first-class graph domain with `kind`-discriminated nodes (`playbook` / `strategy` / `reference`) connected to features and capabilities through `governs` edges. A new `/knowledge` skill absorbs the prior `/configure` skill as a unified intent-inferring surface (read + describe + codify + toggle); `/configure` is tombstoned via `sync-delete-manifest.json`. A new `knowledge:*` CLI subcommand suite ships on both `elevasis` and `elevasis-sdk` over a shared `@repo/core/knowledge/queries` data layer. The Knowledge Browser is wired into `@elevasis/ui` with reusable primitives (`KnowledgeBrowser`, `KnowledgeTree`, `DescribeNodeView`, `KindChip`, `NodeHeader`, `NodeDescribeShell`, etc.) and a build-time MDX codegen pipeline at `@elevasis/sdk/node`. A unified semantic icon-token catalog lives at `@elevasis/core/organization-model` and is shared across core, SDK, UI, Command Center, and external projects. External-parity work makes the bundle zero-config for tenant projects: a dual-mode Vite plugin walks up to `.elevasis`, runs the two-codegen pipeline in-process, and writes artifacts the published Browser already imports -- no flags, no paths, no recipe steps.
6
-
7
- ## Applies to
8
-
9
- All template-derived projects that consume `@elevasis/sdk`, `@elevasis/core`, or `@elevasis/ui`. Specifically:
10
-
11
- - `nirvana-marketing`
12
- - `ZentaraHQ`
13
- - Any future external SDK consumer derived from the `_template` baseline
14
-
15
- ## Required actions
16
-
17
- 1. Pull template changes with `/git-sync` after this train publishes so the refreshed knowledge wiring (template OM defaults, starter `welcome.mdx`, vite plugin pre-wiring, `/knowledge` skill, `/configure` tombstone, scaffold recipe) reaches the project.
18
-
19
- 2. **`/configure` is gone.** The skill was absorbed into `/knowledge`. `/git-sync` removes `external/_template/.claude/skills/configure/` (and its 10 operations files) via `sync-delete-manifest.json` (wave: `knowledge-skill`). Update any tenant-side automation, prompts, or docs that still reference `/configure` -- replace with `/knowledge`. The skill is intent-inferring: classify by natural language (read / describe / codify / toggle), not by verb namespace.
20
-
21
- 3. **`/knowledge` ceremony is unchanged.** The codify ceremony (snapshot -> propose -> confirm -> write -> validate -> rollback) and the two-level model (Level A config-only edits vs. Level B new Zod extension files) are preserved bit-for-bit. The current skill body lives at `.claude/skills/om/SKILL.md` with operations under `.claude/skills/om/operations/` (renamed from the former knowledge skill path), including `codify-level-a.md`, `codify-level-b.md`, plus 8 domain references (`identity`, `customers`, `offerings`, `roles`, `goals`, `techStack`, `features`, `labels`).
22
-
23
- 4. **Vite plugin is pre-wired.** `external/_template/ui/vite.config.ts` imports and spreads `elevasisVite()` from `@elevasis/ui/vite`. After `/git-sync`, the plugin auto-discovers the project via `.elevasis` walk-up, runs both knowledge codegens in-process, and writes:
24
- - `core/config/knowledge/_generated/nodes.ts`
25
- - `core/config/knowledge/_generated/knowledge-bodies.tsx`
26
- - `core/config/knowledge/_generated/knowledge-search-index.json`
27
-
28
- Same behavior in `vite dev` and `vite build`. No flags, no manual codegen step required for the bundle to work.
29
-
30
- 5. **Starter knowledge node lands.** `core/config/knowledge/nodes/welcome.mdx` ships in the template so a fresh clone has a non-empty Browser on first `pnpm -C ui dev`. Replace with tenant-authored MDX nodes as the project codifies real organizational knowledge. Tenant nodes go under `core/config/knowledge/nodes/**/*.mdx` with frontmatter declaring `id`, `kind`, `title`, optional `icon` (semantic token), and an MDX body. Default fallback icons by `kind` apply when `icon` is omitted.
31
-
32
- 6. **Knowledge baseline propagates to the OM.** `core/config/organization-model.ts` now includes baseline knowledge defaults imported from `@elevasis/core/organization-model`. The merge-aware Tier 2 sync preserves tenant overrides while picking up the baseline. After `/git-sync`, verify `resolveOrganizationModel()` still parses (Zod) and `pnpm -C ui exec tsc --noEmit` passes.
33
-
34
- 7. **`knowledge:*` CLI subcommands are available.** From inside the project (any subdirectory):
35
-
36
- ```bash
37
- pnpm exec elevasis-sdk knowledge:ls /by-feature/sales/crm
38
- pnpm exec elevasis-sdk knowledge:ls /by-kind/playbook
39
- pnpm exec elevasis-sdk knowledge:cat <node-id>
40
- pnpm exec elevasis-sdk knowledge:graph <node-id>
41
- ```
42
-
43
- These walk up to `.elevasis`, load the project's OM (with tenant nodes), and print results. Output flags: default text, `--json` envelope, `--ids-only` for piping. The Knowledge Browser sidebar copy buttons emit matching skill-resolvable commands (`/knowledge read <node-id>`, `/knowledge read-folder feature:<id>`, `/knowledge read-folder kind:<kind>`).
44
-
45
- 8. **Semantic icon tokens replace ad-hoc strings.** When authoring or editing nodes (OM or MDX frontmatter), use semantic tokens from the catalog: `nav.*`, `knowledge.*`, `feature.*`, `resource.*`, `integration.*`, plus `custom.*` namespace for tenant extensions. `IconNameSchema` validates them. The UI renders via Tabler mappings in `@elevasis/ui/icons`; library names (`IconBook`, etc.) stay out of the OM/MDX surface.
46
-
47
- 9. **Rebuild and type-check:**
48
-
49
- ```bash
50
- pnpm install
51
- pnpm -C ui build
52
- pnpm -C ui exec tsc --noEmit
53
- pnpm -C operations exec tsc --noEmit
54
- ```
55
-
56
- The first `vite dev` or `vite build` after sync triggers the in-process codegen automatically. To regenerate codegen artifacts manually (one-shot, not normally required):
57
-
58
- ```bash
59
- pnpm exec elevasis-sdk knowledge:generate
60
- ```
61
-
62
- ## Verification
63
-
64
- After applying all actions above:
65
-
66
- - `/configure` skill directory is absent: `external/<project>/.claude/skills/configure/` does not exist after sync.
67
- - `/om` skill is present at `.claude/skills/om/SKILL.md` with the operation files under `.claude/skills/om/operations/`.
68
- - `core/config/knowledge/nodes/welcome.mdx` exists; `core/config/knowledge/_generated/` has been populated by the vite plugin (3 files).
69
- - `pnpm -C ui dev` boots; navigating to `/knowledge` renders the Browser with the welcome node visible in the tree.
70
- - The 5 mount axes resolve: `/knowledge`, `/knowledge/by-feature/$path`, `/knowledge/by-kind/$kind`, `/knowledge/by-owner/$id`, `/knowledge/graph/$nodeId/governs|governed-by`.
71
- - `pnpm exec elevasis-sdk knowledge:ls /by-kind/playbook` returns text output without error.
72
- - `pnpm install` completes cleanly with no unresolved peer warnings.
73
- - `pnpm -C ui exec tsc --noEmit` passes; `pnpm -C operations exec tsc --noEmit` passes.
74
-
75
- ## Not handled by /git-sync
76
-
77
- `/git-sync` propagates template-authored files (package baselines, `welcome.mdx` starter node, generated `_generated/` files, `/knowledge` skill, `/configure` tombstones, vite.config.ts wiring, scaffold recipe doc) but does NOT:
78
-
79
- - Author tenant-specific knowledge MDX nodes. The starter `welcome.mdx` is illustrative; real organizational playbooks, strategies, and reference docs need to be hand-authored under `core/config/knowledge/nodes/**/*.mdx`. Use `/knowledge` for ceremony when codifying.
80
- - Regenerate `_generated/` artifacts on its own. The vite plugin runs the codegens automatically on next `vite dev` / `vite build`. To regenerate manually before booting, run `pnpm exec elevasis-sdk knowledge:generate`.
81
- - Migrate references in tenant code from `/configure` to `/knowledge`. Search the project for `/configure` mentions in `.claude/`, `docs/`, `README.md`, prompts, and CI scripts; rewrite to `/knowledge`. The tombstone deletes the skill files but does not edit downstream references.
82
- - Replace tenant-authored icon strings with semantic tokens. Existing nodes that carried library-specific icon names (`IconBook`, etc.) will continue to render via fallback, but the canonical surface is semantic tokens. Migrate at-touched nodes to `knowledge.*` / `feature.*` / `nav.*` / `custom.*` over time.
83
- - Clear the Vite module-graph cache (`ui/node_modules/.vite`). After upgrading the bundle, clear this directory manually and restart the dev server before verifying the Browser renders -- stale cache can mask a successful generation.
1
+ # Knowledge Bundle Ship-Train
2
+
3
+ ## Why this note exists
4
+
5
+ The Knowledge Map (Browser, CLI, skill, icons, external parity) is being shipped as a coordinated bundle. The Organization Model now treats `knowledge` as a first-class graph domain with `kind`-discriminated nodes (`playbook` / `strategy` / `reference`) connected to features and capabilities through `governs` edges. A new `/knowledge` skill absorbs the prior `/configure` skill as a unified intent-inferring surface (read + describe + codify + toggle); `/configure` is tombstoned via `sync-delete-manifest.json`. A new `knowledge:*` CLI subcommand suite ships on both `elevasis` and `elevasis-sdk` over a shared `@repo/core/knowledge/queries` data layer. The Knowledge Browser is wired into `@elevasis/ui` with reusable primitives (`KnowledgeBrowser`, `KnowledgeTree`, `DescribeNodeView`, `KindChip`, `NodeHeader`, `NodeDescribeShell`, etc.) and a build-time MDX codegen pipeline at `@elevasis/sdk/node`. A unified semantic icon-token catalog lives at `@elevasis/core/organization-model` and is shared across core, SDK, UI, Command Center, and external projects. External-parity work makes the bundle zero-config for tenant projects: a dual-mode Vite plugin walks up to `.elevasis`, runs the two-codegen pipeline in-process, and writes artifacts the published Browser already imports -- no flags, no paths, no recipe steps.
6
+
7
+ ## Applies to
8
+
9
+ All template-derived projects that consume `@elevasis/sdk`, `@elevasis/core`, or `@elevasis/ui`. Specifically:
10
+
11
+ - `nirvana-marketing`
12
+ - `ZentaraHQ`
13
+ - Any future external SDK consumer derived from the `_template` baseline
14
+
15
+ ## Required actions
16
+
17
+ 1. Pull template changes with `/git-sync` after this train publishes so the refreshed knowledge wiring (template OM defaults, starter `welcome.mdx`, vite plugin pre-wiring, `/knowledge` skill, `/configure` tombstone, scaffold recipe) reaches the project.
18
+
19
+ 2. **`/configure` is gone.** The skill was absorbed into `/knowledge`. `/git-sync` removes `external/_template/.claude/skills/configure/` (and its 10 operations files) via `sync-delete-manifest.json` (wave: `knowledge-skill`). Update any tenant-side automation, prompts, or docs that still reference `/configure` -- replace with `/knowledge`. The skill is intent-inferring: classify by natural language (read / describe / codify / toggle), not by verb namespace.
20
+
21
+ 3. **`/knowledge` ceremony is unchanged.** The codify ceremony (snapshot -> propose -> confirm -> write -> validate -> rollback) and the two-level model (Level A config-only edits vs. Level B new Zod extension files) are preserved bit-for-bit. The current skill body lives at `.claude/skills/om/SKILL.md` with operations under `.claude/skills/om/operations/` (renamed from the former knowledge skill path), including `codify-level-a.md`, `codify-level-b.md`, plus 8 domain references (`identity`, `customers`, `offerings`, `roles`, `goals`, `techStack`, `features`, `labels`).
22
+
23
+ 4. **Vite plugin is pre-wired.** `external/_template/ui/vite.config.ts` imports and spreads `elevasisVite()` from `@elevasis/ui/vite`. After `/git-sync`, the plugin auto-discovers the project via `.elevasis` walk-up, runs both knowledge codegens in-process, and writes:
24
+ - `core/config/knowledge/_generated/nodes.ts`
25
+ - `core/config/knowledge/_generated/knowledge-bodies.tsx`
26
+ - `core/config/knowledge/_generated/knowledge-search-index.json`
27
+
28
+ Same behavior in `vite dev` and `vite build`. No flags, no manual codegen step required for the bundle to work.
29
+
30
+ 5. **Starter knowledge node lands.** `core/config/knowledge/nodes/welcome.mdx` ships in the template so a fresh clone has a non-empty Browser on first `pnpm -C ui dev`. Replace with tenant-authored MDX nodes as the project codifies real organizational knowledge. Tenant nodes go under `core/config/knowledge/nodes/**/*.mdx` with frontmatter declaring `id`, `kind`, `title`, optional `icon` (semantic token), and an MDX body. Default fallback icons by `kind` apply when `icon` is omitted.
31
+
32
+ 6. **Knowledge baseline propagates to the OM.** `core/config/organization-model.ts` now includes baseline knowledge defaults imported from `@elevasis/core/organization-model`. The merge-aware Tier 2 sync preserves tenant overrides while picking up the baseline. After `/git-sync`, verify `resolveOrganizationModel()` still parses (Zod) and `pnpm -C ui exec tsc --noEmit` passes.
33
+
34
+ 7. **`knowledge:*` CLI subcommands are available.** From inside the project (any subdirectory):
35
+
36
+ ```bash
37
+ pnpm exec elevasis-sdk knowledge:ls /by-feature/sales/crm
38
+ pnpm exec elevasis-sdk knowledge:ls /by-kind/playbook
39
+ pnpm exec elevasis-sdk knowledge:cat <node-id>
40
+ pnpm exec elevasis-sdk knowledge:graph <node-id>
41
+ ```
42
+
43
+ These walk up to `.elevasis`, load the project's OM (with tenant nodes), and print results. Output flags: default text, `--json` envelope, `--ids-only` for piping. The Knowledge Browser sidebar copy buttons emit matching skill-resolvable commands (`/knowledge read <node-id>`, `/knowledge read-folder feature:<id>`, `/knowledge read-folder kind:<kind>`).
44
+
45
+ 8. **Semantic icon tokens replace ad-hoc strings.** When authoring or editing nodes (OM or MDX frontmatter), use semantic tokens from the catalog: `nav.*`, `knowledge.*`, `feature.*`, `resource.*`, `integration.*`, plus `custom.*` namespace for tenant extensions. `IconNameSchema` validates them. The UI renders via Tabler mappings in `@elevasis/ui/icons`; library names (`IconBook`, etc.) stay out of the OM/MDX surface.
46
+
47
+ 9. **Rebuild and type-check:**
48
+
49
+ ```bash
50
+ pnpm install
51
+ pnpm -C ui build
52
+ pnpm -C ui exec tsc --noEmit
53
+ pnpm -C operations exec tsc --noEmit
54
+ ```
55
+
56
+ The first `vite dev` or `vite build` after sync triggers the in-process codegen automatically. To regenerate codegen artifacts manually (one-shot, not normally required):
57
+
58
+ ```bash
59
+ pnpm exec elevasis-sdk knowledge:generate
60
+ ```
61
+
62
+ ## Verification
63
+
64
+ After applying all actions above:
65
+
66
+ - `/configure` skill directory is absent: `external/<project>/.claude/skills/configure/` does not exist after sync.
67
+ - `/om` skill is present at `.claude/skills/om/SKILL.md` with the operation files under `.claude/skills/om/operations/`.
68
+ - `core/config/knowledge/nodes/welcome.mdx` exists; `core/config/knowledge/_generated/` has been populated by the vite plugin (3 files).
69
+ - `pnpm -C ui dev` boots; navigating to `/knowledge` renders the Browser with the welcome node visible in the tree.
70
+ - The 5 mount axes resolve: `/knowledge`, `/knowledge/by-feature/$path`, `/knowledge/by-kind/$kind`, `/knowledge/by-owner/$id`, `/knowledge/graph/$nodeId/governs|governed-by`.
71
+ - `pnpm exec elevasis-sdk knowledge:ls /by-kind/playbook` returns text output without error.
72
+ - `pnpm install` completes cleanly with no unresolved peer warnings.
73
+ - `pnpm -C ui exec tsc --noEmit` passes; `pnpm -C operations exec tsc --noEmit` passes.
74
+
75
+ ## Not handled by /git-sync
76
+
77
+ `/git-sync` propagates template-authored files (package baselines, `welcome.mdx` starter node, generated `_generated/` files, `/knowledge` skill, `/configure` tombstones, vite.config.ts wiring, scaffold recipe doc) but does NOT:
78
+
79
+ - Author tenant-specific knowledge MDX nodes. The starter `welcome.mdx` is illustrative; real organizational playbooks, strategies, and reference docs need to be hand-authored under `core/config/knowledge/nodes/**/*.mdx`. Use `/knowledge` for ceremony when codifying.
80
+ - Regenerate `_generated/` artifacts on its own. The vite plugin runs the codegens automatically on next `vite dev` / `vite build`. To regenerate manually before booting, run `pnpm exec elevasis-sdk knowledge:generate`.
81
+ - Migrate references in tenant code from `/configure` to `/knowledge`. Search the project for `/configure` mentions in `.claude/`, `docs/`, `README.md`, prompts, and CI scripts; rewrite to `/knowledge`. The tombstone deletes the skill files but does not edit downstream references.
82
+ - Replace tenant-authored icon strings with semantic tokens. Existing nodes that carried library-specific icon names (`IconBook`, etc.) will continue to render via fallback, but the canonical surface is semantic tokens. Migrate at-touched nodes to `knowledge.*` / `feature.*` / `nav.*` / `custom.*` over time.
83
+ - Clear the Vite module-graph cache (`ui/node_modules/.vite`). After upgrading the bundle, clear this directory manually and restart the dev server before verifying the Browser renders -- stale cache can mask a successful generation.