@google-cloud/kcmd 0.0.0-stage → 0.2.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 (150) hide show
  1. package/LICENSE +203 -0
  2. package/README.md +264 -2
  3. package/build/ts/kcmd/cli.js +20252 -0
  4. package/build/ts/kcmd/gcp/alloydb.d.ts +12 -0
  5. package/build/ts/kcmd/gcp/alloydb.js +70 -0
  6. package/build/ts/kcmd/gcp/api.d.ts +29 -0
  7. package/build/ts/kcmd/gcp/api.js +162 -0
  8. package/build/ts/kcmd/gcp/biglake.d.ts +18 -0
  9. package/build/ts/kcmd/gcp/biglake.js +59 -0
  10. package/build/ts/kcmd/gcp/bigquery.d.ts +57 -0
  11. package/build/ts/kcmd/gcp/bigquery.js +134 -0
  12. package/build/ts/kcmd/gcp/context.d.ts +10 -0
  13. package/build/ts/kcmd/gcp/context.js +74 -0
  14. package/build/ts/kcmd/gcp/crm.d.ts +13 -0
  15. package/build/ts/kcmd/gcp/crm.js +91 -0
  16. package/build/ts/kcmd/gcp/dataplex.d.ts +147 -0
  17. package/build/ts/kcmd/gcp/dataplex.js +406 -0
  18. package/build/ts/kcmd/gcp/index.d.ts +3 -0
  19. package/build/ts/kcmd/gcp/index.js +21 -0
  20. package/build/ts/kcmd/gcp/spanner.d.ts +73 -0
  21. package/build/ts/kcmd/gcp/spanner.js +126 -0
  22. package/build/ts/kcmd/index.d.ts +7 -0
  23. package/build/ts/kcmd/index.js +46 -0
  24. package/build/ts/kcmd/layout.d.ts +16 -0
  25. package/build/ts/kcmd/layout.js +31 -0
  26. package/build/ts/kcmd/layouts/documents.d.ts +24 -0
  27. package/build/ts/kcmd/layouts/documents.js +264 -0
  28. package/build/ts/kcmd/layouts/okf.d.ts +31 -0
  29. package/build/ts/kcmd/layouts/okf.js +386 -0
  30. package/build/ts/kcmd/layouts/semantic-model.d.ts +74 -0
  31. package/build/ts/kcmd/layouts/semantic-model.js +621 -0
  32. package/build/ts/kcmd/layouts/standard.d.ts +13 -0
  33. package/build/ts/kcmd/layouts/standard.js +108 -0
  34. package/build/ts/kcmd/manifest.d.ts +34 -0
  35. package/build/ts/kcmd/manifest.js +262 -0
  36. package/build/ts/kcmd/metadata.d.ts +25 -0
  37. package/build/ts/kcmd/metadata.js +8 -0
  38. package/build/ts/kcmd/okf/catalog_residue.d.ts +14 -0
  39. package/build/ts/kcmd/okf/catalog_residue.js +124 -0
  40. package/build/ts/kcmd/okf/concept.d.ts +14 -0
  41. package/build/ts/kcmd/okf/concept.js +110 -0
  42. package/build/ts/kcmd/okf/concept_to_entry.d.ts +10 -0
  43. package/build/ts/kcmd/okf/concept_to_entry.js +281 -0
  44. package/build/ts/kcmd/okf/init_okf_workspace.d.ts +15 -0
  45. package/build/ts/kcmd/okf/init_okf_workspace.js +113 -0
  46. package/build/ts/kcmd/okf/links.d.ts +23 -0
  47. package/build/ts/kcmd/okf/links.js +468 -0
  48. package/build/ts/kcmd/okf/okf_metadata.d.ts +12 -0
  49. package/build/ts/kcmd/okf/okf_metadata.js +99 -0
  50. package/build/ts/kcmd/semantic/bigquery.d.ts +22 -0
  51. package/build/ts/kcmd/semantic/bigquery.js +469 -0
  52. package/build/ts/kcmd/semantic/binding.d.ts +3 -0
  53. package/build/ts/kcmd/semantic/binding.js +92 -0
  54. package/build/ts/kcmd/semantic/catalog_entry.d.ts +24 -0
  55. package/build/ts/kcmd/semantic/catalog_entry.js +35 -0
  56. package/build/ts/kcmd/semantic/converters/owl/convert.d.ts +26 -0
  57. package/build/ts/kcmd/semantic/converters/owl/convert.js +41 -0
  58. package/build/ts/kcmd/semantic/converters/owl/model.d.ts +98 -0
  59. package/build/ts/kcmd/semantic/converters/owl/model.js +30 -0
  60. package/build/ts/kcmd/semantic/converters/owl/parse.d.ts +11 -0
  61. package/build/ts/kcmd/semantic/converters/owl/parse.js +634 -0
  62. package/build/ts/kcmd/semantic/converters/owl/to_ir.d.ts +19 -0
  63. package/build/ts/kcmd/semantic/converters/owl/to_ir.js +390 -0
  64. package/build/ts/kcmd/semantic/deploy_bigquery.d.ts +20 -0
  65. package/build/ts/kcmd/semantic/deploy_bigquery.js +226 -0
  66. package/build/ts/kcmd/semantic/deploy_knowledge_catalog.d.ts +104 -0
  67. package/build/ts/kcmd/semantic/deploy_knowledge_catalog.js +1367 -0
  68. package/build/ts/kcmd/semantic/deploy_spanner.d.ts +15 -0
  69. package/build/ts/kcmd/semantic/deploy_spanner.js +150 -0
  70. package/build/ts/kcmd/semantic/deployment_target.d.ts +93 -0
  71. package/build/ts/kcmd/semantic/deployment_target.js +379 -0
  72. package/build/ts/kcmd/semantic/graph_ddl.d.ts +44 -0
  73. package/build/ts/kcmd/semantic/graph_ddl.js +656 -0
  74. package/build/ts/kcmd/semantic/import_model.d.ts +72 -0
  75. package/build/ts/kcmd/semantic/import_model.js +1698 -0
  76. package/build/ts/kcmd/semantic/ir.d.ts +589 -0
  77. package/build/ts/kcmd/semantic/ir.js +247 -0
  78. package/build/ts/kcmd/semantic/kc_actions.d.ts +45 -0
  79. package/build/ts/kcmd/semantic/kc_actions.js +531 -0
  80. package/build/ts/kcmd/semantic/kc_constraints.d.ts +44 -0
  81. package/build/ts/kcmd/semantic/kc_constraints.js +279 -0
  82. package/build/ts/kcmd/semantic/kc_converter.d.ts +37 -0
  83. package/build/ts/kcmd/semantic/kc_converter.js +839 -0
  84. package/build/ts/kcmd/semantic/kc_custom_types.d.ts +63 -0
  85. package/build/ts/kcmd/semantic/kc_custom_types.js +751 -0
  86. package/build/ts/kcmd/semantic/kc_entries.d.ts +155 -0
  87. package/build/ts/kcmd/semantic/kc_entries.js +284 -0
  88. package/build/ts/kcmd/semantic/kc_ids.d.ts +102 -0
  89. package/build/ts/kcmd/semantic/kc_ids.js +188 -0
  90. package/build/ts/kcmd/semantic/knowledge_catalog.d.ts +29 -0
  91. package/build/ts/kcmd/semantic/knowledge_catalog.js +960 -0
  92. package/build/ts/kcmd/semantic/loader.d.ts +258 -0
  93. package/build/ts/kcmd/semantic/loader.js +3576 -0
  94. package/build/ts/kcmd/semantic/names.d.ts +10 -0
  95. package/build/ts/kcmd/semantic/names.js +85 -0
  96. package/build/ts/kcmd/semantic/osi_converter.d.ts +60 -0
  97. package/build/ts/kcmd/semantic/osi_converter.js +910 -0
  98. package/build/ts/kcmd/semantic/parameters.d.ts +19 -0
  99. package/build/ts/kcmd/semantic/parameters.js +171 -0
  100. package/build/ts/kcmd/semantic/pull_kc.d.ts +10 -0
  101. package/build/ts/kcmd/semantic/pull_kc.js +272 -0
  102. package/build/ts/kcmd/semantic/resolve_inheritance.d.ts +59 -0
  103. package/build/ts/kcmd/semantic/resolve_inheritance.js +346 -0
  104. package/build/ts/kcmd/semantic/resolve_profiles.d.ts +291 -0
  105. package/build/ts/kcmd/semantic/resolve_profiles.js +2003 -0
  106. package/build/ts/kcmd/semantic/runtime/agent_tools.d.ts +93 -0
  107. package/build/ts/kcmd/semantic/runtime/agent_tools.js +243 -0
  108. package/build/ts/kcmd/semantic/runtime/dialect.d.ts +13 -0
  109. package/build/ts/kcmd/semantic/runtime/dialect.js +39 -0
  110. package/build/ts/kcmd/semantic/runtime/runtime.d.ts +88 -0
  111. package/build/ts/kcmd/semantic/runtime/runtime.js +301 -0
  112. package/build/ts/kcmd/semantic/runtime/store.d.ts +112 -0
  113. package/build/ts/kcmd/semantic/runtime/store.js +344 -0
  114. package/build/ts/kcmd/semantic/skills.d.ts +110 -0
  115. package/build/ts/kcmd/semantic/skills.js +697 -0
  116. package/build/ts/kcmd/semantic/source_dialect.d.ts +17 -0
  117. package/build/ts/kcmd/semantic/source_dialect.js +311 -0
  118. package/build/ts/kcmd/semantic/source_entries.d.ts +12 -0
  119. package/build/ts/kcmd/semantic/source_entries.js +341 -0
  120. package/build/ts/kcmd/semantic/spanner.d.ts +18 -0
  121. package/build/ts/kcmd/semantic/spanner.js +60 -0
  122. package/build/ts/kcmd/semantic/sql_expr_utils.d.ts +23 -0
  123. package/build/ts/kcmd/semantic/sql_expr_utils.js +394 -0
  124. package/build/ts/kcmd/semantic/sql_identifiers.d.ts +6 -0
  125. package/build/ts/kcmd/semantic/sql_identifiers.js +267 -0
  126. package/build/ts/kcmd/semantic/sql_parser.d.ts +47 -0
  127. package/build/ts/kcmd/semantic/sql_parser.js +400 -0
  128. package/build/ts/kcmd/semantic/transpile.d.ts +76 -0
  129. package/build/ts/kcmd/semantic/transpile.js +581 -0
  130. package/build/ts/kcmd/semantic/validate.d.ts +70 -0
  131. package/build/ts/kcmd/semantic/validate.js +2266 -0
  132. package/build/ts/kcmd/semantic/yaml_options.d.ts +6 -0
  133. package/build/ts/kcmd/semantic/yaml_options.js +58 -0
  134. package/build/ts/kcmd/semantic/yaml_update.d.ts +26 -0
  135. package/build/ts/kcmd/semantic/yaml_update.js +782 -0
  136. package/build/ts/kcmd/snapshot.d.ts +37 -0
  137. package/build/ts/kcmd/snapshot.js +386 -0
  138. package/build/ts/kcmd/source.d.ts +31 -0
  139. package/build/ts/kcmd/source.js +119 -0
  140. package/build/ts/kcmd/sources/bq-dataset.d.ts +17 -0
  141. package/build/ts/kcmd/sources/bq-dataset.js +131 -0
  142. package/build/ts/kcmd/sources/entrygroup.d.ts +21 -0
  143. package/build/ts/kcmd/sources/entrygroup.js +83 -0
  144. package/build/ts/kcmd/sources/kb.d.ts +21 -0
  145. package/build/ts/kcmd/sources/kb.js +82 -0
  146. package/build/ts/kcmd/sources/semantic-model.d.ts +18 -0
  147. package/build/ts/kcmd/sources/semantic-model.js +48 -0
  148. package/build/ts/kcmd/sync.d.ts +35 -0
  149. package/build/ts/kcmd/sync.js +734 -0
  150. package/package.json +62 -4
@@ -0,0 +1,589 @@
1
+ /**
2
+ * AI-first annotations, from the open format's `ai_context`.
3
+ *
4
+ * The format allows either a bare instructions string (shorthand) or a
5
+ * structured object; the loader normalizes both to this one shape, so the IR
6
+ * always sees the structured form. The parts are grouped in a single object
7
+ * (mirroring the format, e.g. Apache Ossie's `ai_context`) rather than scattered
8
+ * as sibling fields, so nothing is lost and an emitter can still route each part
9
+ * to its own destination (e.g. `instructions` -> a Guidelines aspect,
10
+ * `synonyms` -> glossary links).
11
+ */
12
+ export interface AiContext {
13
+ instructions?: string;
14
+ synonyms?: string[];
15
+ examples?: string[];
16
+ additionalProperties?: Record<string, unknown>;
17
+ }
18
+ /**
19
+ * A vendor-scoped extension block, carried verbatim from the open format's
20
+ * `custom_extensions` (e.g. Apache Ossie's `OSICustomExtension`).
21
+ *
22
+ * `data` is opaque to the IR — a vendor-serialized payload (typically a JSON
23
+ * string) — and is preserved unparsed so nothing is lost and a 1P round-trip
24
+ * stays lossless. Typed views over specific vendors are derived by the
25
+ * consumers that need them, from this same source.
26
+ */
27
+ export interface CustomExtension {
28
+ vendorName: string;
29
+ data: string;
30
+ }
31
+ /**
32
+ * A semantic model: a graph of entities (nodes) connected by relationships
33
+ * (edges), with model-level metrics defined over them.
34
+ *
35
+ * The IR is primarily semantics. The loader reads a model's named
36
+ * `deployments:` list onto `deployments`. In the Google flavor it also folds
37
+ * their target URIs into a model-level GOOGLE `custom_extensions` block for the
38
+ * consumers that read it. A vanilla model lists its deployments in its GOOGLE
39
+ * block, which the loader reads and does not fold.
40
+ */
41
+ export interface SemanticModel {
42
+ name: string;
43
+ description?: string;
44
+ aiContext?: AiContext;
45
+ entities: Entity[];
46
+ relationships: Relationship[];
47
+ metrics: Metric[];
48
+ actions?: Action[];
49
+ constraints?: Constraint[];
50
+ customExtensions?: CustomExtension[];
51
+ version?: '0.2.0.dev0' | '0.2.0.dev0/google';
52
+ profiles?: ProfileSpec[];
53
+ deployments?: DeploymentSpec[];
54
+ excludedMetrics?: string[];
55
+ }
56
+ /**
57
+ * An entity: a node in the semantic graph. Backed by a physical table
58
+ * (`dataSource`), identified by `keys`, and carrying its dimension `fields`.
59
+ */
60
+ export interface Entity {
61
+ name: string;
62
+ dataSource: string;
63
+ authoredSource?: string;
64
+ sourceDialect?: string;
65
+ keys: string[];
66
+ uniqueKeys?: string[][];
67
+ extends?: string[];
68
+ abstract?: boolean;
69
+ description?: string;
70
+ aiContext?: AiContext;
71
+ fields: Field[];
72
+ customExtensions?: CustomExtension[];
73
+ excludedFields?: string[];
74
+ }
75
+ /**
76
+ * Dimension metadata on a field, mirroring the open format's `dimension` block
77
+ * (e.g. Apache Ossie's `OSIDimension`). An empty block still marks the field as
78
+ * a dimension, which enables temporal inference from `type` (see
79
+ * isTimeDimension).
80
+ */
81
+ export interface Dimension {
82
+ isTime?: boolean;
83
+ }
84
+ export declare const ALLOWED_DIALECTS: readonly ["ANSI_SQL", "BIGQUERY", "SPANNER", "MYSQL", "POSTGRES", "ALLOYDB", "SQLSERVER", "SNOWFLAKE", "DATABRICKS"];
85
+ export type SqlDialect = (typeof ALLOWED_DIALECTS)[number];
86
+ export interface DialectExpression {
87
+ dialect: SqlDialect;
88
+ expression: string;
89
+ }
90
+ /**
91
+ * A field: a dimension / attribute of an entity or relationship.
92
+ *
93
+ * Fields describe the data; aggregates are expressed as model-level `Metric`s,
94
+ * not fields.
95
+ *
96
+ * Expression fidelity: the format may supply an expression in several SQL
97
+ * dialects (or as a single string in the Google flavor). The loader keeps every
98
+ * entry in `dialects` in the order written and records `stringForm` (`true`
99
+ * when authored as `expression: "<sql>"`, `false` when authored as a `dialects`
100
+ * list). It also populates `expression` (the target-dialect text, or else the
101
+ * `ANSI_SQL` one) and `importedExpression` (the first other vendor entry, with
102
+ * its `importedDialect`) via `pickDialect`. A bound field sets at least one of
103
+ * `expression`, `importedExpression` or a non-empty `dialects` (the loader sets
104
+ * one of the first two whenever it writes the third). When only
105
+ * `importedExpression` is present, `expression` awaits a transpile pass (see
106
+ * ./transpile) that fills it from the imported form.
107
+ */
108
+ export interface Field {
109
+ name: string;
110
+ expression?: string;
111
+ importedExpression?: string;
112
+ importedDialect?: string;
113
+ dialects?: DialectExpression[];
114
+ stringForm?: boolean;
115
+ dimension?: Dimension;
116
+ label?: string;
117
+ description?: string;
118
+ type?: DataType;
119
+ aiContext?: AiContext;
120
+ customExtensions?: CustomExtension[];
121
+ }
122
+ /**
123
+ * The open format's `datatype` vocabulary, mirroring Apache Ossie's `DataType`:
124
+ * a CLOSED, case-sensitive set of logical types, independent of physical
125
+ * representation. It is optional; omit it when the type is unknown. `Opaque`
126
+ * marks an unknown type: the loader reads it as no type, and the catalog stores
127
+ * it where a type is required. No custom extension supplies a real type for
128
+ * it. The loader enforces this set at parse time, so a `type` on the IR is
129
+ * always one of these.
130
+ */
131
+ export declare const DATA_TYPES: readonly ["String", "Integer", "Decimal", "Float", "Boolean", "Date", "Time", "DateTime", "DateTimeTz", "Opaque"];
132
+ export type DataType = typeof DATA_TYPES[number];
133
+ /**
134
+ * Normalizes a raw `datatype` string according to the document's flavor.
135
+ *
136
+ * In `0.2.0.dev0`, matching is strictly case-sensitive. In `0.2.0.dev0/google`,
137
+ * matching is case-insensitive and returns the canonical spelling. In both
138
+ * flavors, an omitted `datatype` and `Opaque` normalize to `type: undefined`.
139
+ */
140
+ export declare function normalizeDataType(raw: string | undefined, version: '0.2.0.dev0' | '0.2.0.dev0/google'): {
141
+ ok: true;
142
+ type: Exclude<DataType, 'Opaque'> | undefined;
143
+ } | {
144
+ ok: false;
145
+ };
146
+ /**
147
+ * A field's effective temporal-dimension role, mirroring the open format's
148
+ * `is_time_dimension()` (e.g. Apache Ossie's `OSIField`): a field must carry
149
+ * `dimension` metadata to be a dimension at all; within it an explicit `isTime`
150
+ * takes precedence, otherwise the role defaults from a temporal `type`.
151
+ */
152
+ export declare function isTimeDimension(field: Field): boolean;
153
+ export declare function fieldBinding(field: Pick<Field, 'expression' | 'importedExpression'>): string | undefined;
154
+ export declare const FIELD_BINDING_KEYS: readonly ["expression", "dialects", "stringForm", "importedExpression", "importedDialect"];
155
+ export declare const FIELD_DEFINITION_KEYS: readonly ["type", "label", "dimension", "description", "aiContext", "customExtensions"];
156
+ /**
157
+ * Whether a field is bound to a column under the current binding: it carries an
158
+ * expression, an imported vendor expression, or a non-empty dialect list.
159
+ * `stringForm` and `importedDialect` describe a binding and are not one on
160
+ * their own. Inheritance, profile pruning and push validation use this test.
161
+ * A graph generator asks a narrower question, whether the field has SQL for its
162
+ * engine (see expressionForDialect), so a bound field can still be left out of
163
+ * one engine's graph.
164
+ */
165
+ export declare function isFieldBound(field: Pick<Field, 'expression' | 'importedExpression' | 'dialects'>): boolean;
166
+ /**
167
+ * Whether a relationship's `to_columns` cover the primary key or a unique key.
168
+ * A key is covered when every one of its columns is among `to_columns`, so a
169
+ * superset of a key covers it, since each row still matches at most one target
170
+ * row. Column names compare as BigQuery compares them: ignoring case, and
171
+ * without the backticks that only quote a name.
172
+ */
173
+ export declare function coversKey(toColumns: string[], primaryKey: string[], uniqueKeys: string[][]): boolean;
174
+ /**
175
+ * Selects the SQL expression for a target engine from a Field or Metric.
176
+ *
177
+ * With a non-empty `dialects` list, returns the entry matching `targetDialect`;
178
+ * failing that, and where the target is not already `ANSI_SQL`, falls back to
179
+ * the `ANSI_SQL` entry; failing both, returns `undefined`. With `dialects`
180
+ * empty or absent, returns `item.importedExpression` when `importedDialect` is
181
+ * the target, and `item.expression` otherwise.
182
+ */
183
+ export declare function expressionForDialect(item: {
184
+ expression?: string;
185
+ dialects?: DialectExpression[];
186
+ importedExpression?: string;
187
+ importedDialect?: string;
188
+ }, targetDialect: (typeof ALLOWED_DIALECTS)[number]): string | undefined;
189
+ /**
190
+ * A relationship: a directed foreign-key edge in the semantic graph, from
191
+ * `source` to `destination`. The join pairs the endpoints' columns positionally
192
+ * (`source.columns[i] = destination.columns[i]`): the source's foreign-key
193
+ * columns referencing the destination's key columns.
194
+ */
195
+ export interface Relationship {
196
+ name: string;
197
+ source: RelationshipEnd;
198
+ destination: RelationshipEnd;
199
+ association?: Association;
200
+ description?: string;
201
+ aiContext?: AiContext;
202
+ customExtensions?: CustomExtension[];
203
+ }
204
+ /**
205
+ * One endpoint of a relationship: the entity it attaches to and the columns on
206
+ * that entity's own table that participate in the join.
207
+ */
208
+ export interface RelationshipEnd {
209
+ entity: string;
210
+ columns: string[];
211
+ }
212
+ /**
213
+ * An association (junction) table backing a many-to-many relationship.
214
+ *
215
+ * A many-to-many link cannot be a foreign key: an FK column holds a single
216
+ * value and so references at most one row (a to-one direction), which cannot
217
+ * encode a pairing where each side maps to many of the other. The pairs instead
218
+ * live in a separate junction table, one row per (source, destination) -- e.g.
219
+ * an `enrollment` row per (student, course).
220
+ *
221
+ * Unlike a direct foreign key -- which the open format expresses and the loader
222
+ * produces -- a junction edge is backed by its OWN table (`dataSource`) with
223
+ * its OWN key (`keys`) and may carry edge `fields` (properties of the
224
+ * association itself, e.g. an enrollment's grade). Each side names the columns
225
+ * ON THE JUNCTION TABLE that reference the key of the endpoint entity's node
226
+ * (see nodeKey). The open format has no association-table syntax yet, so this
227
+ * is produced by hand-built IR (or a future format extension), not the loader.
228
+ */
229
+ export interface Association {
230
+ dataSource: string;
231
+ keys: string[];
232
+ sourceColumns: string[];
233
+ destinationColumns: string[];
234
+ fields?: Field[];
235
+ }
236
+ /**
237
+ * A metric: a model-level, named aggregate.
238
+ *
239
+ * Because it lives on the model rather than a single entity, a metric may span
240
+ * multiple entities — its `expression` can reference fields across the graph,
241
+ * joined via relationships. See `entity` for the single attach point and how
242
+ * it's derived.
243
+ *
244
+ * Expression fidelity mirrors `Field`: a target/canonical `expression` and/or
245
+ * the original vendor `importedExpression` (+ `importedDialect`).
246
+ */
247
+ export interface Metric {
248
+ name: string;
249
+ expression?: string;
250
+ importedExpression?: string;
251
+ importedDialect?: string;
252
+ dialects?: DialectExpression[];
253
+ stringForm?: boolean;
254
+ entity?: string;
255
+ authoredEntity?: string;
256
+ description?: string;
257
+ type?: DataType;
258
+ aiContext?: AiContext;
259
+ customExtensions?: CustomExtension[];
260
+ }
261
+ /**
262
+ * An action: a model-level, named write operation over the ontology -- the
263
+ * write-side counterpart to a metric's read. Like a metric it lives on the
264
+ * model (not a single entity) and may span several entities via its typed
265
+ * `parameters`.
266
+ *
267
+ * The model contributes only what the ontology can say that a plain tool schema
268
+ * cannot: parameters typed from the ontology (a projected one takes its type
269
+ * and its wording from the field it names) and the
270
+ * constraints that gate the call. The mechanics of running it are delegated to
271
+ * an `executor` (e.g. an MCP tool in Agent Registry); `description` is
272
+ * informational and does not affect runtime.
273
+ */
274
+ export interface Action {
275
+ name: string;
276
+ description?: string;
277
+ executor?: Executor;
278
+ parameters: ActionParameter[];
279
+ guards?: string[];
280
+ affects?: AffectedConcept[];
281
+ aiContext?: AiContext;
282
+ customExtensions?: CustomExtension[];
283
+ }
284
+ /**
285
+ * One concept an action changes, and how.
286
+ *
287
+ * `concept` is the authored name of an entity or a relationship, kept verbatim
288
+ * for a lossless round-trip. Which of the two it is, is deliberately NOT
289
+ * recorded: it is a fact about the model, it changes nothing about what the
290
+ * entry means, and the same three operations apply either way. Whoever needs
291
+ * the distinction -- validate does, to know which fields the concept has --
292
+ * resolves it against the model, so there is one place it can be wrong instead
293
+ * of two. The loader warns about a name that resolves to neither.
294
+ *
295
+ * `operation` and `fields` are optional, and their absence means "unspecified"
296
+ * rather than "nothing". The open format accepts a bare name as shorthand for
297
+ * an entry with neither -- `affects: [Order]` is the coarse blast radius the
298
+ * proposal describes -- so a model can start there and add precision only
299
+ * where a rule needs it.
300
+ */
301
+ export interface AffectedConcept {
302
+ concept: string;
303
+ operation?: ConceptOperation;
304
+ fields?: string[];
305
+ }
306
+ /**
307
+ * What an action does to a concept it affects.
308
+ *
309
+ * One vocabulary covers entities and relationships alike, because both admit
310
+ * the same three acts. An edge is not only added and removed: a many-to-many
311
+ * relationship is backed by a junction table with fields of its own (see
312
+ * Association), so modifying an enrollment's grade is as ordinary as modifying
313
+ * an order's total. Splitting the vocabulary by kind would make that change
314
+ * inexpressible and would buy a policy predicate nothing.
315
+ */
316
+ export declare const CONCEPT_OPERATIONS: readonly ["create", "modify", "delete"];
317
+ export type ConceptOperation = typeof CONCEPT_OPERATIONS[number];
318
+ /**
319
+ * One input to an action. Always a SCALAR value: a parameter carries a value,
320
+ * never an object the runtime has to go and find first.
321
+ *
322
+ * There are two ways to author one.
323
+ *
324
+ * DERIVED. `concept` plus `field` PROJECT the parameter from a field the model
325
+ * already declares -- of an entity or of a relationship, the same two things
326
+ * `affects` may name:
327
+ *
328
+ * - {concept: Account, field: accountId}
329
+ * - {name: sourceAccountId, concept: Account, field: accountId,
330
+ * description: The account money leaves.}
331
+ *
332
+ * `name` defaults to the field's name, so the one-key form above declares a
333
+ * parameter called `accountId`. `type` MUST NOT be authored: it is the field's,
334
+ * and a parameter restating it is a second place for it to be wrong. The
335
+ * loader copies `type`, `description`, `label` and `aiContext` down from the
336
+ * field; the parameter's own wording wins over the field's where it states any,
337
+ * and the type never does.
338
+ *
339
+ * STANDALONE. Nothing in the model corresponds -- a free-text `memo`, a reason
340
+ * code -- so the parameter declares its own scalar `type` and names no field:
341
+ *
342
+ * - {name: memo, type: String, description: Why the credit was issued.}
343
+ *
344
+ * `concept` and `field` are kept on the IR ALONGSIDE what they resolved to, so
345
+ * the reference round-trips as the author wrote it while a consumer that does
346
+ * not have the model -- a catalog reader, an agent holding only the published
347
+ * aspect -- can still read the resolved type.
348
+ *
349
+ * `required` and `default` are always the parameter's own and are never
350
+ * inherited: a field describes what a thing HAS, and says nothing about whether
351
+ * a CALL must supply a value for it.
352
+ *
353
+ * `type` is optional only as an AUTHORED key. After a load it is populated on
354
+ * every parameter -- stated by a standalone one, resolved from the field by a
355
+ * derived one. The single exception is a parameter the loader could resolve
356
+ * neither way, which is kept verbatim and warned about, and which validate.ts
357
+ * then rejects.
358
+ */
359
+ export interface ActionParameter {
360
+ name: string;
361
+ type?: string;
362
+ concept?: string;
363
+ field?: string;
364
+ description?: string;
365
+ label?: string;
366
+ aiContext?: AiContext;
367
+ required?: boolean;
368
+ default?: unknown;
369
+ }
370
+ /**
371
+ * The mechanics of how an action is executed: exactly one kind, tagged so
372
+ * consumers can switch on it. The open format expresses it as an object with a
373
+ * single kind key (`mcp` / `rest` / `grpc`); the loader normalizes that to this
374
+ * discriminated union. Other kinds (SQL DML, CLI, ...) can be added later.
375
+ */
376
+ export type Executor = {
377
+ kind: 'mcp';
378
+ mcp: McpExecutor;
379
+ } | {
380
+ kind: 'rest';
381
+ rest: RestExecutor;
382
+ } | {
383
+ kind: 'grpc';
384
+ grpc: GrpcExecutor;
385
+ } | {
386
+ kind: 'sql';
387
+ sql: SqlExecutor;
388
+ };
389
+ /**
390
+ * A SQL executor: the write itself, declared in the model as an ordered list of
391
+ * DML statements.
392
+ *
393
+ * The other three executor kinds name a system that performs the write, so what
394
+ * the write does is opaque to the model. This one contains it, which buys two
395
+ * things the opaque kinds cannot offer.
396
+ *
397
+ * - The blast radius is checkable. `affects` can be read against the
398
+ * statements rather than taken on trust.
399
+ * - A guard becomes a real gate. An MCP, REST or gRPC call commits inside a
400
+ * system the caller does not control, so a write it performed could not be
401
+ * rolled back if the rest of the action failed; a statement run in a
402
+ * database transaction can be. Guards settle before that transaction opens,
403
+ * so a refusal leaves the store untouched and no check ever observes the
404
+ * write it gates.
405
+ *
406
+ * The narrowness is the safety argument, and validate.ts enforces it. A
407
+ * statement is a single INSERT, UPDATE or DELETE. Every `@name` it binds names
408
+ * a parameter the action declares, so an argument reaches the store as a bound
409
+ * value and never as SQL. There is no control flow, no statement composed at
410
+ * call time, and no way for a caller to supply a statement of its own: an
411
+ * action whose body arrives with the call declares nothing, and a gate cannot
412
+ * check what was never declared.
413
+ *
414
+ * A row the statement inserts needs a primary key, and the statement is what
415
+ * decides where it comes from: a UUID function the store offers, a value the
416
+ * caller passes as an ordinary parameter, or the key column left out where it
417
+ * has a default. The runtime generates nothing on its behalf. A key that comes
418
+ * in as a parameter is one the caller chooses, and the check in validate.ts
419
+ * reads only a statement's first word, so an upsert passes and overwrites the
420
+ * row that key names.
421
+ */
422
+ export interface SqlExecutor {
423
+ statements: string[];
424
+ }
425
+ export declare const SQL_EXECUTOR_VERBS: readonly ["INSERT", "UPDATE", "DELETE"];
426
+ /**
427
+ * An MCP executor: references a tool already registered in Agent Registry, by
428
+ * the MCP server's resource name plus the tool's in-server selector. Agent
429
+ * Registry is the canonical source consumed at runtime (e.g. by an agent).
430
+ */
431
+ export interface McpExecutor {
432
+ server: string;
433
+ tool: string;
434
+ }
435
+ /** A REST executor: an HTTP endpoint and method. */
436
+ export interface RestExecutor {
437
+ endpoint: string;
438
+ method: string;
439
+ }
440
+ /** A gRPC executor: a fully-qualified service and method. */
441
+ export interface GrpcExecutor {
442
+ service: string;
443
+ method: string;
444
+ }
445
+ /**
446
+ * What a violated constraint does to the write that tripped it.
447
+ *
448
+ * - `reject` the write is refused. Nobody is allowed to approve it, which
449
+ * is what makes the rule an invariant rather than a policy.
450
+ * - `escalate` the write is held and a person decides. The rule is a business
451
+ * threshold, so somebody is allowed to say yes.
452
+ * - `warn` the write proceeds and the violation is reported.
453
+ *
454
+ * An engine reading the catalog needs this in order to route. Without it every
455
+ * rule publishes with the same shape, and a $30 credit that needs a supervisor
456
+ * is indistinguishable from one that is simply forbidden.
457
+ *
458
+ * This is a disposition, not a magnitude, and the two are deliberately separate
459
+ * keys. `escalate` is not "between" reject and warn on a scale of badness: it is
460
+ * a different control flow, and what it really states is that an approver
461
+ * exists. Two rules can be equally grave -- both guarding a million-dollar write
462
+ * -- and differ only in whether anyone in the organization is entitled to say
463
+ * yes. See CONSTRAINT_SEVERITIES for the magnitude.
464
+ *
465
+ * `escalate` names that an approver exists. It does not name who: an approver
466
+ * role is not modeled yet.
467
+ *
468
+ * The consequence is a field rather than something a `judgment` states in its
469
+ * own prose, because three things need it without running a judge. An
470
+ * unrunnable judge -- none configured, a failed call, a timeout -- still has to
471
+ * route the breach it could not evaluate. A search for the rules that can stop
472
+ * a write cannot read prose. And a policy DSL states its effect in the rule
473
+ * head, so a rule whose consequence is only implied by its wording cannot be
474
+ * lowered into OPA or Cedar.
475
+ *
476
+ * A judgment may declare any of the three, `reject` included. What settles a
477
+ * judgment can decide two identical proposals differently, and `reject` leaves
478
+ * no appeal, so that pairing is the riskiest thing this model can express. It
479
+ * is still a bet an organization is entitled to place, and refusing to
480
+ * represent it would move the policy out of the catalog rather than prevent it.
481
+ * It is made auditable instead: `evaluation` publishes `judged` beside the
482
+ * word, so "unappealable rules settled by a model" is one query. `onViolation`
483
+ * is required on a judgment rather than defaulted, because a forgotten word
484
+ * would produce exactly that pairing silently.
485
+ *
486
+ * A constraint's word is the consequence of the one condition it states. A
487
+ * policy whose conditions carry different consequences is written as several
488
+ * constraints, which `guards` on an action lists together; the strictest
489
+ * consequence among the violated ones is what the action does. See
490
+ * docs/semantic-model/actions.md for a worked policy.
491
+ *
492
+ * STATUS: the declared word is published, read back, and routed on for the
493
+ * rules something settles. A judgment is settled where an action names it in
494
+ * `guards`, and `warn` reports while `reject` and `escalate` stop the call;
495
+ * `escalate` says so in the refusal, because nothing here has an approver to
496
+ * route to. An expression is still text nothing computes, so its word decides
497
+ * nothing yet.
498
+ */
499
+ export declare const VIOLATION_EFFECTS: readonly ["reject", "escalate", "warn"];
500
+ export type ViolationEffect = (typeof VIOLATION_EFFECTS)[number];
501
+ /**
502
+ * How grave a violation of a constraint is, independent of what the engine does
503
+ * about it.
504
+ *
505
+ * Ranking and reporting want this: which of forty violations in a batch to show
506
+ * a human first, which to page on. Enforcement does not -- that is
507
+ * `onViolation`, and the split is the point. A `low` rule may still be an
508
+ * absolute `reject`, and a `critical` one may be a `warn` because the
509
+ * organization is not ready to block on it yet.
510
+ *
511
+ * The scale is the ordinary four-point one, and it avoids `warning` on purpose:
512
+ * a severity called `warning` sitting beside an effect called `warn` would read
513
+ * as the same statement made twice.
514
+ *
515
+ * STATUS: authored, published and read back. Nothing ranks or routes on it yet.
516
+ */
517
+ export declare const CONSTRAINT_SEVERITIES: readonly ["critical", "high", "medium", "low"];
518
+ export type ConstraintSeverity = (typeof CONSTRAINT_SEVERITIES)[number];
519
+ /**
520
+ * A constraint: a model-level, named invariant over the ontology, stated in
521
+ * words and settled by a language model reading the call that would break it.
522
+ *
523
+ * A `judgment` is the rule as a sentence: *the credit memo must name a specific
524
+ * service failure*, *the order must be within the customer's standing limit*.
525
+ * It is the one body a constraint has, so settling any rule is a model call;
526
+ * `expression` is a reserved key the loader refuses. See "what a judgment
527
+ * costs" in docs/semantic-model/actions.md.
528
+ *
529
+ * A judgment states ONE condition, because the consequence is carried by
530
+ * `onViolation` and one word cannot route two branches. A policy whose branches
531
+ * end differently -- a missing approval is held for a person, a disguised
532
+ * transaction is refused -- is written as one constraint per branch, and
533
+ * `guards` on the action lists them together.
534
+ *
535
+ * What the catalog offers a judged rule is identity and governance, never
536
+ * determinism: one name, one owner, one version, one declared consequence, and
537
+ * the same text for every caller instead of prose re-improvised per call. A
538
+ * language model can still decide two identical proposals differently, and no
539
+ * schema changes that. `onViolation` is required so that the consequence of
540
+ * that non-determinism is always stated rather than inherited.
541
+ *
542
+ * STATUS: authored, validated, published and enforced. kcmd carries a
543
+ * constraint to Knowledge Catalog, where an agent can read the rules a model
544
+ * requires. Where an action names a constraint in `guards`, the judgment is
545
+ * settled before the transaction opens, which is why it reads the attempted
546
+ * call and never the state the write produced: a rule about the RESULT of a
547
+ * write is not something this body states. A caller that supplies no judge gets
548
+ * nothing settled -- the action is refused rather than run past the rule.
549
+ *
550
+ * `description` is the error text a violation would surface, so write it to
551
+ * steer an agent's next move -- "reduce the order quantity or choose another
552
+ * customer" -- rather than to label the rule.
553
+ */
554
+ export interface Constraint {
555
+ name: string;
556
+ judgment?: string;
557
+ description?: string;
558
+ onViolation?: ViolationEffect;
559
+ severity?: ConstraintSeverity;
560
+ aiContext?: AiContext;
561
+ }
562
+ export interface DeploymentSpec {
563
+ name: string;
564
+ target: string;
565
+ profile?: string;
566
+ }
567
+ export interface ProfileEntityBinding {
568
+ name: string;
569
+ source?: string;
570
+ primaryKey?: string[];
571
+ uniqueKeys?: string[][];
572
+ fields?: Array<Pick<Field, 'name' | 'expression' | 'dialects' | 'stringForm' | 'importedExpression' | 'importedDialect'>>;
573
+ fieldsExclude?: string[];
574
+ }
575
+ export interface ProfileRelationshipBinding {
576
+ name: string;
577
+ fromColumns: string[];
578
+ toColumns: string[];
579
+ }
580
+ export interface ProfileSpec {
581
+ name: string;
582
+ entities: ProfileEntityBinding[];
583
+ relationships: ProfileRelationshipBinding[];
584
+ metricsExclude?: '*' | string[];
585
+ actions?: Array<{
586
+ name: string;
587
+ executor?: Executor | null;
588
+ }>;
589
+ }