@elevasis/sdk 1.29.0 → 1.30.1
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/dist/cli.cjs +1610 -594
- package/dist/index.d.ts +87 -1
- package/dist/index.js +30 -25
- package/dist/node/index.d.ts +84 -1
- package/dist/test-utils/index.d.ts +84 -1
- package/dist/test-utils/index.js +242 -23
- package/dist/worker/index.js +1 -0
- package/package.json +4 -4
- package/reference/claude-config/rules/topbar-actions.md +70 -0
- package/reference/claude-config/skills/om/SKILL.md +18 -1
- package/reference/claude-config/skills/om/operations/scaffold.md +153 -0
- package/reference/claude-config/sync-notes/2026-05-04-knowledge-bundle.md +83 -83
- package/reference/claude-config/sync-notes/2026-05-14-organization-model-ontology-refactor.md +45 -45
- package/reference/claude-config/sync-notes/2026-05-15-om-skill-rename-and-write-family.md +52 -52
- package/reference/claude-config/sync-notes/2026-05-17-sdk-boundary-consolidation.md +33 -33
- package/reference/claude-config/sync-notes/2026-05-20-om-define-helpers.md +32 -32
- package/reference/claude-config/sync-notes/2026-05-22-access-model-and-right-panel.md +43 -43
- package/reference/claude-config/sync-notes/2026-05-22-lead-gen-tenant-config.md +40 -40
- package/reference/claude-config/sync-notes/2026-05-22-org-model-multi-file-split.md +61 -61
- package/reference/claude-config/sync-notes/2026-05-23-branding-names-to-identity.md +49 -49
- package/reference/claude-config/sync-notes/2026-05-23-lead-gen-manage-access.md +31 -31
- package/reference/claude-config/sync-notes/2026-05-23-om-deployment-drift-detection.md +42 -42
- package/reference/claude-config/sync-notes/2026-05-23-om-full-model-deploy-contract.md +33 -33
- package/reference/claude-config/sync-notes/2026-05-23-ui-sdk-package-fixes.md +37 -37
- package/reference/claude-config/sync-notes/2026-05-24-platform-invite-router-core-baseline.md +28 -28
- package/reference/claude-config/sync-notes/2026-05-24-system-interface-readiness.md +43 -43
- package/reference/claude-config/sync-notes/2026-05-25-invitation-login-loader.md +26 -0
- package/reference/claude-config/sync-notes/2026-05-25-om-topbar-requests.md +33 -0
- package/reference/claude-config/sync-notes/2026-05-25-system-interface-profile-registry-and-substrate.md +35 -0
- package/reference/claude-config/sync-notes/2026-05-25-tenant-om-scaffold-cli.md +49 -0
- package/reference/claude-config/sync-notes/2026-05-25-vibe-operate-intent.md +47 -0
- package/reference/examples/organization-model.ts +18 -0
- package/reference/rules/organization-model.md +4 -1
- package/reference/rules/organization-os.md +7 -1
- package/reference/rules/ui.md +207 -207
- package/reference/rules/vibe.md +52 -18
- package/reference/scaffold/index.mdx +9 -7
- package/reference/scaffold/operations/scaffold-maintenance.md +14 -4
- package/reference/scaffold/reference/contracts.md +423 -338
- package/reference/scaffold/reference/glossary.md +14 -2
- package/reference/scaffold/reference/system-interface-capabilities.md +50 -0
- /package/reference/claude-config/skills/deploy/{skill.md → SKILL.md} +0 -0
package/dist/test-utils/index.js
CHANGED
|
@@ -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
|
-
|
|
8631
|
-
|
|
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
|
|
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 {
|
package/dist/worker/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@elevasis/sdk",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.30.1",
|
|
4
4
|
"description": "SDK for building Elevasis organization resources",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -58,9 +58,9 @@
|
|
|
58
58
|
"tsup": "^8.0.0",
|
|
59
59
|
"typescript": "5.9.2",
|
|
60
60
|
"zod": "^4.1.0",
|
|
61
|
-
"@repo/core": "0.
|
|
62
|
-
"@repo/
|
|
63
|
-
"@repo/
|
|
61
|
+
"@repo/core": "0.38.0",
|
|
62
|
+
"@repo/typescript-config": "0.0.0",
|
|
63
|
+
"@repo/eslint-config": "0.0.0"
|
|
64
64
|
},
|
|
65
65
|
"scripts": {
|
|
66
66
|
"lint": "eslint src --max-warnings 0",
|
|
@@ -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
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
# Scaffold: New OM Entries via `om:scaffold:*` CLI
|
|
2
|
+
|
|
3
|
+
`om:scaffold:*` is the guided-creation surface for adding new entries to the tenant Organization Model. Each command prompts for missing fields, prints the proposed TypeScript / MDX block under `--dry-run`, and (when run without `--dry-run`) writes into the canonical authoring file under `core/config/organization-model/**` or `core/config/knowledge/nodes/`.
|
|
4
|
+
|
|
5
|
+
This operation is invoked by `/om` when intent classifies as **Codify-new-entry** (a net-new System, Resource, Role, Knowledge node, or a fill-pass against a conformance-gap JSON) rather than a Level-A field edit. For existing-field edits, dispatch to `codify-level-a.md` instead.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## When to Use
|
|
10
|
+
|
|
11
|
+
| Intent signal | Dispatch |
|
|
12
|
+
| ----------------------------------------------- | -------------------------------- |
|
|
13
|
+
| "Add a new system for …", "we have an X system" | `om:scaffold:system` |
|
|
14
|
+
| "Add a workflow / resource called …" | `om:scaffold:resource` |
|
|
15
|
+
| "Add a role …", "we need a … role" | `om:scaffold:role` |
|
|
16
|
+
| "Add a knowledge node / playbook / strategy …" | `om:scaffold:knowledge` |
|
|
17
|
+
| Conformance gate produced a gap JSON to apply | `om:scaffold:fill --gaps <path>` |
|
|
18
|
+
|
|
19
|
+
For existing-field edits (changing a description, toggling a system, renaming a label), use the Codify Level-A ceremony — do not scaffold.
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## CLI Surface
|
|
24
|
+
|
|
25
|
+
All commands run from inside `external/<project>/` (or any descendant — `elevasis-sdk` walks up to the `.elevasis` marker). Add `--dry-run` to any command to preview the generated TypeScript / MDX without writing.
|
|
26
|
+
|
|
27
|
+
| Command | Purpose | Writes to |
|
|
28
|
+
| ----------------------- | ---------------------------------------------------------------------------------------------------- | ------------------------------------------- |
|
|
29
|
+
| `om:scaffold:system` | Guide creation of a new System entry. Optional `--api-backed` emits an `apiInterface` block. | `core/config/organization-model/systems.ts` |
|
|
30
|
+
| `om:scaffold:resource` | Add a new workflow Resource descriptor with `systemPath` attachment and an ontology `primaryAction`. | `core/config/organization-model/systems.ts` |
|
|
31
|
+
| `om:scaffold:role` | Add a new Role to the profile domain. | `core/config/organization-model/profile.ts` |
|
|
32
|
+
| `om:scaffold:knowledge` | Create a new MDX knowledge node file under the requested kind / system mount. | `core/config/knowledge/nodes/` |
|
|
33
|
+
| `om:scaffold:fill` | Non-interactive apply of a conformance-gap JSON produced by the conformance gate (Agent 2a). | Per-file as recorded in the JSON. |
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## Common Options
|
|
38
|
+
|
|
39
|
+
| Flag | Behavior |
|
|
40
|
+
| --------------------------- | ------------------------------------------------------------------------------------ | -------- | --------- | -------- |
|
|
41
|
+
| `--dry-run` | Print proposed block; write nothing. Always run this first when in doubt. |
|
|
42
|
+
| `-h`, `--help` | Print command-specific help. |
|
|
43
|
+
| `--id <id>` | Pre-fill the canonical id (prompted if absent). |
|
|
44
|
+
| `--title <title>` | Pre-fill display title (prompted if absent — `system`, `resource`, `role`). |
|
|
45
|
+
| `--system-path <path>` | Attach Resource or Knowledge to an existing System (prompted if absent). |
|
|
46
|
+
| `--api-backed` | (`system` only) Emit an `apiInterface` block; reminds you to populate `resourceIds`. |
|
|
47
|
+
| `--primary-action <action>` | (`resource` only) Pre-fill ontology primary action id. |
|
|
48
|
+
| `--kind <kind>` | (`knowledge` only) `playbook | strategy | reference | policy`. |
|
|
49
|
+
| `--gaps <path>` | (`fill` only) Required path to the conformance-gap JSON. |
|
|
50
|
+
| `--skipped <path>` | (`fill` only) Output path for gaps that still need manual input. |
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## Step-by-Step
|
|
55
|
+
|
|
56
|
+
### Step 1: Pre-flight read
|
|
57
|
+
|
|
58
|
+
Before scaffolding, run a single `om:describe` against the parent System (for Resource / Knowledge scaffolds) or the profile domain (for Role scaffolds). This grounds the proposed id, system path, and ontology references in current model state. Skipping this step routinely produces ids that collide with existing entries.
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
pnpm exec elevasis-sdk om:describe sales.crm
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Step 2: Dry-run
|
|
65
|
+
|
|
66
|
+
Always preview first. Each command prints the exact TypeScript / MDX block it would write.
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
pnpm exec elevasis-sdk om:scaffold:system --dry-run
|
|
70
|
+
pnpm exec elevasis-sdk om:scaffold:resource --dry-run
|
|
71
|
+
pnpm exec elevasis-sdk om:scaffold:role --dry-run
|
|
72
|
+
pnpm exec elevasis-sdk om:scaffold:knowledge --dry-run
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
The dry-run output is the diff you would present to the user during a Codify proposal. Show it verbatim before asking for confirmation.
|
|
76
|
+
|
|
77
|
+
### Step 3: Confirm
|
|
78
|
+
|
|
79
|
+
Pause for explicit user confirmation, exactly like Codify Level-A Step 3. Permission prompts also gate the underlying write.
|
|
80
|
+
|
|
81
|
+
### Step 4: Write
|
|
82
|
+
|
|
83
|
+
Re-run the command without `--dry-run`. The CLI:
|
|
84
|
+
|
|
85
|
+
1. Asserts the project is in split layout (`core/config/organization-model/{profile,systems,navigation}.ts`); on monolithic projects it errors with a guidance message rather than guessing where to write.
|
|
86
|
+
2. Inserts the new block alongside existing entries of the same kind.
|
|
87
|
+
3. Reports the touched file path.
|
|
88
|
+
|
|
89
|
+
### Step 5: Validate
|
|
90
|
+
|
|
91
|
+
Always run both gates after a scaffold write:
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
pnpm -C operations check-types # tsc --noEmit
|
|
95
|
+
pnpm -C operations check # elevasis-sdk resource validator (incl. conformance gate)
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
The new conformance gate (shipped in `@elevasis/sdk@1.30+`) will catch a System that declares API-backed Resources but no `apiInterface`. If it fires after a `system` scaffold, either:
|
|
99
|
+
|
|
100
|
+
- Re-run `om:scaffold:system --api-backed` to add the `apiInterface` block, or
|
|
101
|
+
- Run `om:scaffold:fill --gaps <gaps.json>` against the gate's emitted gaps file.
|
|
102
|
+
|
|
103
|
+
### Step 6: Rollback on failure
|
|
104
|
+
|
|
105
|
+
If either validation gate fails, restore the touched file from the snapshot captured in Step 1 of the parent `/om` Codify ceremony. The scaffold CLI does not perform its own rollback — the ceremony around it does.
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## `om:scaffold:fill` — Conformance Gap Pass
|
|
110
|
+
|
|
111
|
+
`om:scaffold:fill` is the non-interactive counterpart to the four guided scaffolders. It consumes a JSON file shaped like the output of the conformance gate (the new deploy preflight introduced alongside `@elevasis/core@0.38` + `@elevasis/sdk@1.30`) and writes the missing fields it can derive without user input. Gaps that require a choice (e.g. picking a `readinessProfile`) land in the `--skipped` output for manual review.
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
# After the conformance gate prints a gaps file:
|
|
115
|
+
pnpm exec elevasis-sdk om:scaffold:fill --gaps .elevasis/conformance-gaps.json --dry-run
|
|
116
|
+
pnpm exec elevasis-sdk om:scaffold:fill --gaps .elevasis/conformance-gaps.json --skipped .elevasis/conformance-skipped.json
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
`fill` is idempotent for already-applied gaps; it skips entries that no longer match the live model.
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
## Layout Guard
|
|
124
|
+
|
|
125
|
+
Every `om:scaffold:*` command requires the split layout under `core/config/organization-model/`:
|
|
126
|
+
|
|
127
|
+
- `profile.ts` — identity, customers, offerings, roles, goals, techStack, labels
|
|
128
|
+
- `systems.ts` — systems + system-attached resources
|
|
129
|
+
- `navigation.ts` — navigation surfaces and sidebar wiring
|
|
130
|
+
|
|
131
|
+
On a monolithic `core/config/organization-model.ts`, the command errors with a one-line instruction to split first. The split step is owned by an upstream `/om` workflow — do not hand-split during a scaffold.
|
|
132
|
+
|
|
133
|
+
---
|
|
134
|
+
|
|
135
|
+
## Related Operations
|
|
136
|
+
|
|
137
|
+
- `codify-level-a.md` — existing-field edits (the default Codify pipeline)
|
|
138
|
+
- `codify-level-b.md` — net-new Zod extension files under `core/config/extensions/`
|
|
139
|
+
- `verify.md` — model-coherence checks (the in-memory doctor)
|
|
140
|
+
|
|
141
|
+
---
|
|
142
|
+
|
|
143
|
+
## Caller Contract (when dispatched from `/om`)
|
|
144
|
+
|
|
145
|
+
When `/om` classifies a Codify-new-entry intent, it should:
|
|
146
|
+
|
|
147
|
+
1. Pick the correct sub-command from the table above.
|
|
148
|
+
2. Pre-fill any options it can confidently extract from the conversation (`--id`, `--title`, `--system-path`, `--api-backed`, etc.) so the CLI does not re-prompt for them.
|
|
149
|
+
3. Always pass `--dry-run` on the first invocation and show the output to the user.
|
|
150
|
+
4. On user confirmation, re-invoke without `--dry-run`.
|
|
151
|
+
5. Run the Step 5 validators and report the result. Roll back if either fails.
|
|
152
|
+
|
|
153
|
+
Do not skip the dry-run round-trip. The scaffolders write into the authoring source of truth — silent writes erode the trust the `/om` ceremony exists to protect.
|