@telorun/kernel 0.87.0 → 0.89.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/kernel.ts CHANGED
@@ -7,6 +7,7 @@ import {
7
7
  diffManifests,
8
8
  flattenForAnalyzer,
9
9
  flattenLoadedModule,
10
+ implicitEvalSites,
10
11
  isModuleKind,
11
12
  nodeIdFor,
12
13
  Loader,
@@ -1022,7 +1023,26 @@ export class Kernel implements IKernel {
1022
1023
  );
1023
1024
  if (manifest.kind === "Telo.Application") {
1024
1025
  rootApplicationManifest = manifest;
1025
- this._appName = (manifest.metadata as { name?: string } | undefined)?.name;
1026
+ const appName = (manifest.metadata as { name?: string } | undefined)?.name;
1027
+ this._appName = appName;
1028
+ // `Self` names the declaring module's own kinds, ungated — the import
1029
+ // controller registers it for every imported library, and the
1030
+ // analyzer registers it for a root module too. Without the kernel's
1031
+ // half a root Application declaring its own `Telo.Definition` and
1032
+ // instantiating it as `kind: Self.<Kind>` passed `telo check` and
1033
+ // failed at boot with "no module imported with alias 'Self'".
1034
+ //
1035
+ // The module's OWN NAME resolves the same kinds, for the same reason
1036
+ // it needs no import: `<module>.<Kind>` IS the canonical identity the
1037
+ // registry keys on and every diagnostic prints, so an author reading
1038
+ // one copies that spelling back into the manifest. The analyzer
1039
+ // resolves it (it is canonical, not an alias), the kernel did not, and
1040
+ // the gap passed `telo check` and failed at boot with "no module
1041
+ // imported with alias '<name>'".
1042
+ if (appName) {
1043
+ this.rootContext.registerUngatedAlias("Self", appName);
1044
+ this.rootContext.registerUngatedAlias(appName, appName);
1045
+ }
1026
1046
  }
1027
1047
  }
1028
1048
  this.rootContext.registerManifest(manifest);
@@ -1671,7 +1691,11 @@ export class Kernel implements IKernel {
1671
1691
  const ownEval = definition?.schema
1672
1692
  ? buildEvalPaths(definition.schema)
1673
1693
  : { compile: [], runtime: [] };
1674
- const compile = [...parentEval.compile, ...ownEval.compile];
1694
+ // A base-form child's own fields are construction inputs read once by
1695
+ // `base:`, so they are compile-eval without annotation — the rule is the
1696
+ // analyzer's, shared so `telo check` and dispatch agree on it.
1697
+ const implicitEval = implicitEvalSites(definition);
1698
+ const compile = [...parentEval.compile, ...ownEval.compile, ...implicitEval.compile];
1675
1699
  const runtime = [...parentEval.runtime, ...ownEval.runtime];
1676
1700
 
1677
1701
  // Embedded files are read here, at the single instance-production site, and
@@ -118,41 +118,40 @@ const KNOWN_CAPABILITIES = [
118
118
  /** Rule 8: `throws:` is only meaningful on Telo.Invocable or Telo.Runnable.
119
119
  * On Service/Mount/Provider/Type/etc. a thrown error is a boot-time failure,
120
120
  * not a structured runtime error for a downstream caller, so declaring one
121
- * is a schema error. */
122
- const forbidThrows = { not: { required: ["throws"] } };
121
+ * is a schema error.
122
+ *
123
+ * Spelled as a `false` schema at the property rather than `not: {required}` so
124
+ * the failure NAMES THE KEY: AJV reports `not` at the document root with
125
+ * nothing about the inner schema, which left the whole union unable to say
126
+ * which key was at fault — and the reducer then preferred a branch whose
127
+ * `capability` const merely disagreed, reporting `/capability must be equal to
128
+ * constant` about a document whose capability was right and whose `throws:` was
129
+ * wrong. This form reports `/throws is not allowed here`. */
130
+ /** One capability's branch. `throws` and `capability` live in ONE `properties`
131
+ * map, built here — spreading a second object carrying `properties` silently
132
+ * REPLACES the capability constant, which turns every forbidding branch into
133
+ * "any definition with a capability and no throws" and makes the whole `oneOf`
134
+ * match several branches at once. */
135
+ const capabilityBranch = (capability: string, mayThrow: boolean) => ({
136
+ required: ["capability"],
137
+ properties: {
138
+ capability: { const: capability },
139
+ ...(mayThrow ? {} : { throws: false }),
140
+ },
141
+ });
123
142
 
124
143
  export const ResourceDefinitionSchema = {
125
144
  ...baseDefinition,
126
145
  oneOf: [
127
- {
128
- required: ["capability"],
129
- properties: { capability: { const: "Telo.Service" } },
130
- ...forbidThrows,
131
- },
132
- { required: ["capability"], properties: { capability: { const: "Telo.Runnable" } } },
133
- { required: ["capability"], properties: { capability: { const: "Telo.Invocable" } } },
134
- {
135
- required: ["capability"],
136
- properties: { capability: { const: "Telo.Provider" } },
137
- ...forbidThrows,
138
- },
139
- {
140
- required: ["capability"],
141
- properties: { capability: { const: "Telo.Type" } },
142
- ...forbidThrows,
143
- },
144
- {
145
- required: ["capability"],
146
- properties: { capability: { const: "Telo.Mount" } },
147
- ...forbidThrows,
148
- },
149
- {
150
- // A sink is written to directly, never dispatched, so a thrown error is a
151
- // boot-time failure rather than a structured runtime error for a caller.
152
- required: ["capability"],
153
- properties: { capability: { const: "Telo.Sink" } },
154
- ...forbidThrows,
155
- },
146
+ capabilityBranch("Telo.Service", false),
147
+ capabilityBranch("Telo.Runnable", true),
148
+ capabilityBranch("Telo.Invocable", true),
149
+ capabilityBranch("Telo.Provider", false),
150
+ capabilityBranch("Telo.Type", false),
151
+ capabilityBranch("Telo.Mount", false),
152
+ // A sink is written to directly, never dispatched, so a thrown error is a
153
+ // boot-time failure rather than a structured runtime error for a caller.
154
+ capabilityBranch("Telo.Sink", false),
156
155
  // Unknown/absent capability: open schema for third-party extensibility
157
156
  {
158
157
  not: {