@truefoundry/tfy-infra-engine 0.1.3-canary.abfd26a → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -100,21 +100,15 @@ if (!result.driftReport.valid) {
100
100
 
101
101
  ### `engine.upgrade(envelope, currentFiles, previousManifest)`
102
102
 
103
- Update platform files to new template versions. Always renders new files and returns a pre-upgrade drift report. The `sourceBlocked` flag indicates a template source mismatch -- callers enforce blocking policy (FR-029).
103
+ Update platform files to new template versions. Performs pre-upgrade drift detection and source mismatch blocking.
104
104
 
105
105
  ```typescript
106
106
  const result = await engine.upgrade(envelope, currentFiles, previousManifest);
107
-
108
107
  if (result.sourceBlocked) {
109
- // Template source changed -- caller decides whether to proceed
110
- console.log('Source mismatch detected');
111
- }
112
- if (!result.driftReport.valid) {
113
- // Managed files were modified since last render
108
+ console.log('Upgrade blocked: template source mismatch');
109
+ } else if (!result.driftReport.valid) {
114
110
  console.log('Pre-upgrade drift detected');
115
111
  }
116
-
117
- // result.files always contains newly rendered files, even when sourceBlocked
118
112
  ```
119
113
 
120
114
  ### `engine.hashOnly(envelope)`
@@ -152,15 +146,15 @@ if (!result.valid) {
152
146
  // inputs now has defaults applied in-place
153
147
  ```
154
148
 
155
- ### Bundle Validation
149
+ ### Template JSON Validation
156
150
 
157
- Validate the top-level structure of a `bundle.json` file:
151
+ Validate the top-level structure of a `template.json` file:
158
152
 
159
153
  ```typescript
160
- import { validateBundle } from '@truefoundry/tfy-infra-engine';
154
+ import { validateTemplateJson } from '@truefoundry/tfy-infra-engine';
161
155
 
162
- const parsed = JSON.parse(fs.readFileSync('bundle.json', 'utf-8'));
163
- const { metadata, jsonSchema } = validateBundle(parsed);
156
+ const parsed = JSON.parse(fs.readFileSync('template.json', 'utf-8'));
157
+ const { metadata, jsonSchema } = validateTemplateJson(parsed);
164
158
  // metadata: { name, version, description? }
165
159
  // jsonSchema: the raw JSON Schema object
166
160
  ```
@@ -275,11 +269,11 @@ try {
275
269
  case EngineErrorCode.INPUT_VALIDATION_FAILED:
276
270
  console.log('Invalid inputs:', error.details);
277
271
  break;
278
- case EngineErrorCode.BUNDLE_NOT_FOUND:
279
- console.log('bundle.json not found in template directory');
272
+ case EngineErrorCode.TEMPLATE_JSON_NOT_FOUND:
273
+ console.log('template.json not found in template directory');
280
274
  break;
281
- case EngineErrorCode.BUNDLE_INVALID:
282
- console.log('bundle.json has invalid structure:', error.message);
275
+ case EngineErrorCode.TEMPLATE_JSON_INVALID:
276
+ console.log('template.json has invalid structure:', error.message);
283
277
  break;
284
278
  case EngineErrorCode.TOFU_NOT_FOUND:
285
279
  console.log('Install OpenTofu or use skipFormat option');
package/dist/index.d.mts CHANGED
@@ -4,12 +4,14 @@
4
4
  declare enum EngineErrorCode {
5
5
  TEMPLATE_NOT_FOUND = "TEMPLATE_NOT_FOUND",
6
6
  NETWORK_ERROR = "NETWORK_ERROR",
7
+ GITHUB_NOT_FOUND = "GITHUB_NOT_FOUND",
8
+ GITHUB_RATE_LIMITED = "GITHUB_RATE_LIMITED",
7
9
  FILE_NOT_FOUND = "FILE_NOT_FOUND",
8
10
  HTTPS_AUTH_FAILED = "HTTPS_AUTH_FAILED",
9
11
  SCHEMA_INVALID = "SCHEMA_INVALID",
10
12
  INPUT_VALIDATION_FAILED = "INPUT_VALIDATION_FAILED",
11
- BUNDLE_NOT_FOUND = "BUNDLE_NOT_FOUND",
12
- BUNDLE_INVALID = "BUNDLE_INVALID",
13
+ TEMPLATE_JSON_NOT_FOUND = "TEMPLATE_JSON_NOT_FOUND",
14
+ TEMPLATE_JSON_INVALID = "TEMPLATE_JSON_INVALID",
13
15
  TEMPLATE_SYNTAX_ERROR = "TEMPLATE_SYNTAX_ERROR",
14
16
  TOFU_NOT_FOUND = "TOFU_NOT_FOUND",
15
17
  TOFU_FMT_FAILED = "TOFU_FMT_FAILED",
@@ -40,7 +42,7 @@ declare class EngineError extends Error {
40
42
  *
41
43
  * CHANGE (008): All Zod-based converter functions and zod-to-json-schema
42
44
  * import removed. Only the JSONSchema7 type interface remains.
43
- * Templates provide JSON Schema directly via bundle.json.
45
+ * Templates provide JSON Schema directly via template.json.
44
46
  */
45
47
  /**
46
48
  * JSON Schema Draft-07 type.
@@ -172,7 +174,7 @@ interface RenderOptions {
172
174
  skipFormat?: boolean;
173
175
  }
174
176
  /**
175
- * Metadata about a template, sourced from the "metadata" key in bundle.json.
177
+ * Metadata about a template, sourced from the "template" key in template.json.
176
178
  */
177
179
  interface TemplateMetadata {
178
180
  /** Template name */
@@ -186,12 +188,12 @@ interface TemplateMetadata {
186
188
  * A remote template package containing source files and schema.
187
189
  *
188
190
  * CHANGE (008): Replaced `schema: TemplateSchema` with `metadata` + `jsonSchema`.
189
- * Metadata comes from bundle.json "metadata" key; schema from "jsonSchema" key.
191
+ * Metadata comes from template.json "template" key; schema from "schema" key.
190
192
  */
191
193
  interface Template {
192
- /** Template metadata from bundle.json → "metadata" key */
194
+ /** Template metadata from template.json → "template" key */
193
195
  metadata: TemplateMetadata;
194
- /** JSON Schema Draft-07 from bundle.json → "jsonSchema" key */
196
+ /** JSON Schema Draft-07 from template.json → "schema" key */
195
197
  jsonSchema: JSONSchema7;
196
198
  /** Map of output paths to HBS content (rendered via Handlebars) */
197
199
  files: Map<string, string>;
@@ -421,36 +423,36 @@ interface HclEngine {
421
423
  }
422
424
 
423
425
  /**
424
- * Bundle structure validation using AJV.
426
+ * Template JSON structure validation using AJV.
425
427
  *
426
- * Validates the top-level structure of a bundle against the
427
- * bundleSchema (JSON Schema Draft-07) defined in bundle-schema.ts.
428
+ * Validates the top-level structure of template.json against the
429
+ * templateJsonSchema (JSON Schema Draft-07) defined in template-json-schema.ts.
428
430
  *
429
431
  * Reference: R-006, data-model.md validator.ts
430
432
  */
431
433
 
432
434
  /**
433
- * Result of validating a bundle.
435
+ * Result of validating a template.json file.
434
436
  */
435
- interface BundleValidationResult {
437
+ interface TemplateJsonResult {
436
438
  metadata: TemplateMetadata;
437
439
  jsonSchema: JSONSchema7;
438
440
  }
439
441
  /**
440
- * Validate the structure of a parsed bundle.
442
+ * Validate the structure of a parsed template.json file.
441
443
  *
442
444
  * Checks:
443
- * - Data is an object with "metadata" and "jsonSchema" keys
444
- * - metadata.name is a non-empty string
445
- * - metadata.version is a semver string (x.y.z)
446
- * - metadata.description is an optional string
447
- * - jsonSchema is a non-null object with type: "object" and properties
445
+ * - Data is an object with "template" and "schema" keys
446
+ * - template.name is a non-empty string
447
+ * - template.version is a semver string (x.y.z)
448
+ * - template.description is an optional string
449
+ * - schema is a non-null object with type: "object" and properties
448
450
  *
449
- * @param data - Parsed JSON content from a bundle
451
+ * @param data - Parsed JSON content from template.json
450
452
  * @returns Validated metadata and JSON Schema
451
- * @throws EngineError with BUNDLE_INVALID on failure
453
+ * @throws EngineError with TEMPLATE_JSON_INVALID on failure
452
454
  */
453
- declare function validateBundle(data: unknown): BundleValidationResult;
455
+ declare function validateTemplateJson(data: unknown): TemplateJsonResult;
454
456
 
455
457
  /**
456
458
  * AJV-based JSON Schema input validation.
@@ -478,20 +480,20 @@ declare function validateBundle(data: unknown): BundleValidationResult;
478
480
  declare function validateJsonSchemaStructure(schema: JSONSchema7): void;
479
481
 
480
482
  /**
481
- * JSON Schema (Draft-07) for bundle.json files.
483
+ * JSON Schema (Draft-07) for template.json files.
482
484
  *
483
- * This is the source of truth for bundle structure validation.
485
+ * This is the source of truth for template.json validation.
484
486
  * Used by validator.ts via AJV for runtime validation.
485
487
  *
486
488
  * Validates:
487
- * - "metadata" key: name (required, non-empty), version (semver, required), description (optional string)
488
- * - "jsonSchema" key: must be a JSON Schema object with type: "object" and a properties key
489
+ * - "template" key: name (required, non-empty), version (semver, required), description (optional string)
490
+ * - "schema" key: must be a JSON Schema object with type: "object" and a properties key
489
491
  *
490
- * Note: No additionalProperties: false at root level -- extra top-level keys are allowed
491
- * for forward compatibility (e.g., uiSchema, files, staticFiles, version).
492
+ * Note: No additionalProperties: false at root level extra top-level keys are allowed
493
+ * for forward compatibility.
492
494
  */
493
495
 
494
- declare const bundleSchema: JSONSchema7;
496
+ declare const templateJsonSchema: JSONSchema7;
495
497
 
496
498
  /**
497
499
  * Check if tofu is available in the system.
@@ -625,4 +627,4 @@ declare function parseHeader(content: string): TfyStatusHeader | undefined;
625
627
  */
626
628
  declare function createEngine(): HclEngine;
627
629
 
628
- export { type BundleValidationResult, DEFAULT_PREFIX, type DriftReport, type DriftType, EngineError, EngineErrorCode, type Envelope, type FileEntry, type FileMap, type HashOnlyResult, type InstallResult, type JSONSchema7, type Manifest, type Resolver, type ResolverOptions, type Template, type TemplateMetadata, type UpgradeResult, type VerifyResult, type VersionInfo, bundleSchema, canonicalHash, classifyFile, createEngine, getCanonicalHashScriptPath, isTofuAvailable, parseHeader, validateBundle, validateJsonSchemaStructure };
630
+ export { DEFAULT_PREFIX, type DriftReport, type DriftType, EngineError, EngineErrorCode, type Envelope, type FileEntry, type FileMap, type HashOnlyResult, type InstallResult, type JSONSchema7, type Manifest, type Resolver, type ResolverOptions, type Template, type UpgradeResult, type VerifyResult, type VersionInfo, canonicalHash, classifyFile, createEngine, getCanonicalHashScriptPath, isTofuAvailable, parseHeader, templateJsonSchema, validateJsonSchemaStructure, validateTemplateJson };
package/dist/index.d.ts CHANGED
@@ -4,12 +4,14 @@
4
4
  declare enum EngineErrorCode {
5
5
  TEMPLATE_NOT_FOUND = "TEMPLATE_NOT_FOUND",
6
6
  NETWORK_ERROR = "NETWORK_ERROR",
7
+ GITHUB_NOT_FOUND = "GITHUB_NOT_FOUND",
8
+ GITHUB_RATE_LIMITED = "GITHUB_RATE_LIMITED",
7
9
  FILE_NOT_FOUND = "FILE_NOT_FOUND",
8
10
  HTTPS_AUTH_FAILED = "HTTPS_AUTH_FAILED",
9
11
  SCHEMA_INVALID = "SCHEMA_INVALID",
10
12
  INPUT_VALIDATION_FAILED = "INPUT_VALIDATION_FAILED",
11
- BUNDLE_NOT_FOUND = "BUNDLE_NOT_FOUND",
12
- BUNDLE_INVALID = "BUNDLE_INVALID",
13
+ TEMPLATE_JSON_NOT_FOUND = "TEMPLATE_JSON_NOT_FOUND",
14
+ TEMPLATE_JSON_INVALID = "TEMPLATE_JSON_INVALID",
13
15
  TEMPLATE_SYNTAX_ERROR = "TEMPLATE_SYNTAX_ERROR",
14
16
  TOFU_NOT_FOUND = "TOFU_NOT_FOUND",
15
17
  TOFU_FMT_FAILED = "TOFU_FMT_FAILED",
@@ -40,7 +42,7 @@ declare class EngineError extends Error {
40
42
  *
41
43
  * CHANGE (008): All Zod-based converter functions and zod-to-json-schema
42
44
  * import removed. Only the JSONSchema7 type interface remains.
43
- * Templates provide JSON Schema directly via bundle.json.
45
+ * Templates provide JSON Schema directly via template.json.
44
46
  */
45
47
  /**
46
48
  * JSON Schema Draft-07 type.
@@ -172,7 +174,7 @@ interface RenderOptions {
172
174
  skipFormat?: boolean;
173
175
  }
174
176
  /**
175
- * Metadata about a template, sourced from the "metadata" key in bundle.json.
177
+ * Metadata about a template, sourced from the "template" key in template.json.
176
178
  */
177
179
  interface TemplateMetadata {
178
180
  /** Template name */
@@ -186,12 +188,12 @@ interface TemplateMetadata {
186
188
  * A remote template package containing source files and schema.
187
189
  *
188
190
  * CHANGE (008): Replaced `schema: TemplateSchema` with `metadata` + `jsonSchema`.
189
- * Metadata comes from bundle.json "metadata" key; schema from "jsonSchema" key.
191
+ * Metadata comes from template.json "template" key; schema from "schema" key.
190
192
  */
191
193
  interface Template {
192
- /** Template metadata from bundle.json → "metadata" key */
194
+ /** Template metadata from template.json → "template" key */
193
195
  metadata: TemplateMetadata;
194
- /** JSON Schema Draft-07 from bundle.json → "jsonSchema" key */
196
+ /** JSON Schema Draft-07 from template.json → "schema" key */
195
197
  jsonSchema: JSONSchema7;
196
198
  /** Map of output paths to HBS content (rendered via Handlebars) */
197
199
  files: Map<string, string>;
@@ -421,36 +423,36 @@ interface HclEngine {
421
423
  }
422
424
 
423
425
  /**
424
- * Bundle structure validation using AJV.
426
+ * Template JSON structure validation using AJV.
425
427
  *
426
- * Validates the top-level structure of a bundle against the
427
- * bundleSchema (JSON Schema Draft-07) defined in bundle-schema.ts.
428
+ * Validates the top-level structure of template.json against the
429
+ * templateJsonSchema (JSON Schema Draft-07) defined in template-json-schema.ts.
428
430
  *
429
431
  * Reference: R-006, data-model.md validator.ts
430
432
  */
431
433
 
432
434
  /**
433
- * Result of validating a bundle.
435
+ * Result of validating a template.json file.
434
436
  */
435
- interface BundleValidationResult {
437
+ interface TemplateJsonResult {
436
438
  metadata: TemplateMetadata;
437
439
  jsonSchema: JSONSchema7;
438
440
  }
439
441
  /**
440
- * Validate the structure of a parsed bundle.
442
+ * Validate the structure of a parsed template.json file.
441
443
  *
442
444
  * Checks:
443
- * - Data is an object with "metadata" and "jsonSchema" keys
444
- * - metadata.name is a non-empty string
445
- * - metadata.version is a semver string (x.y.z)
446
- * - metadata.description is an optional string
447
- * - jsonSchema is a non-null object with type: "object" and properties
445
+ * - Data is an object with "template" and "schema" keys
446
+ * - template.name is a non-empty string
447
+ * - template.version is a semver string (x.y.z)
448
+ * - template.description is an optional string
449
+ * - schema is a non-null object with type: "object" and properties
448
450
  *
449
- * @param data - Parsed JSON content from a bundle
451
+ * @param data - Parsed JSON content from template.json
450
452
  * @returns Validated metadata and JSON Schema
451
- * @throws EngineError with BUNDLE_INVALID on failure
453
+ * @throws EngineError with TEMPLATE_JSON_INVALID on failure
452
454
  */
453
- declare function validateBundle(data: unknown): BundleValidationResult;
455
+ declare function validateTemplateJson(data: unknown): TemplateJsonResult;
454
456
 
455
457
  /**
456
458
  * AJV-based JSON Schema input validation.
@@ -478,20 +480,20 @@ declare function validateBundle(data: unknown): BundleValidationResult;
478
480
  declare function validateJsonSchemaStructure(schema: JSONSchema7): void;
479
481
 
480
482
  /**
481
- * JSON Schema (Draft-07) for bundle.json files.
483
+ * JSON Schema (Draft-07) for template.json files.
482
484
  *
483
- * This is the source of truth for bundle structure validation.
485
+ * This is the source of truth for template.json validation.
484
486
  * Used by validator.ts via AJV for runtime validation.
485
487
  *
486
488
  * Validates:
487
- * - "metadata" key: name (required, non-empty), version (semver, required), description (optional string)
488
- * - "jsonSchema" key: must be a JSON Schema object with type: "object" and a properties key
489
+ * - "template" key: name (required, non-empty), version (semver, required), description (optional string)
490
+ * - "schema" key: must be a JSON Schema object with type: "object" and a properties key
489
491
  *
490
- * Note: No additionalProperties: false at root level -- extra top-level keys are allowed
491
- * for forward compatibility (e.g., uiSchema, files, staticFiles, version).
492
+ * Note: No additionalProperties: false at root level extra top-level keys are allowed
493
+ * for forward compatibility.
492
494
  */
493
495
 
494
- declare const bundleSchema: JSONSchema7;
496
+ declare const templateJsonSchema: JSONSchema7;
495
497
 
496
498
  /**
497
499
  * Check if tofu is available in the system.
@@ -625,4 +627,4 @@ declare function parseHeader(content: string): TfyStatusHeader | undefined;
625
627
  */
626
628
  declare function createEngine(): HclEngine;
627
629
 
628
- export { type BundleValidationResult, DEFAULT_PREFIX, type DriftReport, type DriftType, EngineError, EngineErrorCode, type Envelope, type FileEntry, type FileMap, type HashOnlyResult, type InstallResult, type JSONSchema7, type Manifest, type Resolver, type ResolverOptions, type Template, type TemplateMetadata, type UpgradeResult, type VerifyResult, type VersionInfo, bundleSchema, canonicalHash, classifyFile, createEngine, getCanonicalHashScriptPath, isTofuAvailable, parseHeader, validateBundle, validateJsonSchemaStructure };
630
+ export { DEFAULT_PREFIX, type DriftReport, type DriftType, EngineError, EngineErrorCode, type Envelope, type FileEntry, type FileMap, type HashOnlyResult, type InstallResult, type JSONSchema7, type Manifest, type Resolver, type ResolverOptions, type Template, type UpgradeResult, type VerifyResult, type VersionInfo, canonicalHash, classifyFile, createEngine, getCanonicalHashScriptPath, isTofuAvailable, parseHeader, templateJsonSchema, validateJsonSchemaStructure, validateTemplateJson };
package/dist/index.js CHANGED
@@ -33,15 +33,15 @@ __export(index_exports, {
33
33
  DEFAULT_PREFIX: () => DEFAULT_PREFIX,
34
34
  EngineError: () => EngineError,
35
35
  EngineErrorCode: () => EngineErrorCode,
36
- bundleSchema: () => bundleSchema,
37
36
  canonicalHash: () => canonicalHash,
38
37
  classifyFile: () => classifyFile,
39
38
  createEngine: () => createEngine,
40
39
  getCanonicalHashScriptPath: () => getCanonicalHashScriptPath,
41
40
  isTofuAvailable: () => isTofuAvailable,
42
41
  parseHeader: () => parseHeader,
43
- validateBundle: () => validateBundle,
44
- validateJsonSchemaStructure: () => validateJsonSchemaStructure
42
+ templateJsonSchema: () => templateJsonSchema,
43
+ validateJsonSchemaStructure: () => validateJsonSchemaStructure,
44
+ validateTemplateJson: () => validateTemplateJson
45
45
  });
46
46
  module.exports = __toCommonJS(index_exports);
47
47
 
@@ -49,12 +49,14 @@ module.exports = __toCommonJS(index_exports);
49
49
  var EngineErrorCode = /* @__PURE__ */ ((EngineErrorCode2) => {
50
50
  EngineErrorCode2["TEMPLATE_NOT_FOUND"] = "TEMPLATE_NOT_FOUND";
51
51
  EngineErrorCode2["NETWORK_ERROR"] = "NETWORK_ERROR";
52
+ EngineErrorCode2["GITHUB_NOT_FOUND"] = "GITHUB_NOT_FOUND";
53
+ EngineErrorCode2["GITHUB_RATE_LIMITED"] = "GITHUB_RATE_LIMITED";
52
54
  EngineErrorCode2["FILE_NOT_FOUND"] = "FILE_NOT_FOUND";
53
55
  EngineErrorCode2["HTTPS_AUTH_FAILED"] = "HTTPS_AUTH_FAILED";
54
56
  EngineErrorCode2["SCHEMA_INVALID"] = "SCHEMA_INVALID";
55
57
  EngineErrorCode2["INPUT_VALIDATION_FAILED"] = "INPUT_VALIDATION_FAILED";
56
- EngineErrorCode2["BUNDLE_NOT_FOUND"] = "BUNDLE_NOT_FOUND";
57
- EngineErrorCode2["BUNDLE_INVALID"] = "BUNDLE_INVALID";
58
+ EngineErrorCode2["TEMPLATE_JSON_NOT_FOUND"] = "TEMPLATE_JSON_NOT_FOUND";
59
+ EngineErrorCode2["TEMPLATE_JSON_INVALID"] = "TEMPLATE_JSON_INVALID";
58
60
  EngineErrorCode2["TEMPLATE_SYNTAX_ERROR"] = "TEMPLATE_SYNTAX_ERROR";
59
61
  EngineErrorCode2["TOFU_NOT_FOUND"] = "TOFU_NOT_FOUND";
60
62
  EngineErrorCode2["TOFU_FMT_FAILED"] = "TOFU_FMT_FAILED";
@@ -99,12 +101,12 @@ var EngineError = class _EngineError extends Error {
99
101
  // src/schema/validator.ts
100
102
  var import_ajv = __toESM(require("ajv"));
101
103
 
102
- // src/schema/bundle-schema.ts
103
- var bundleSchema = {
104
+ // src/schema/template-json-schema.ts
105
+ var templateJsonSchema = {
104
106
  $schema: "http://json-schema.org/draft-07/schema#",
105
107
  type: "object",
106
108
  properties: {
107
- metadata: {
109
+ template: {
108
110
  type: "object",
109
111
  properties: {
110
112
  name: { type: "string", minLength: 1 },
@@ -114,7 +116,7 @@ var bundleSchema = {
114
116
  required: ["name", "version"],
115
117
  additionalProperties: false
116
118
  },
117
- jsonSchema: {
119
+ schema: {
118
120
  type: "object",
119
121
  description: "JSON Schema Draft-07 defining template inputs",
120
122
  properties: {
@@ -125,7 +127,7 @@ var bundleSchema = {
125
127
  required: ["type", "properties"]
126
128
  }
127
129
  },
128
- required: ["metadata", "jsonSchema"]
130
+ required: ["template", "schema"]
129
131
  };
130
132
 
131
133
  // src/schema/validator.ts
@@ -134,51 +136,54 @@ var ajv = new import_ajv.default({
134
136
  strict: false,
135
137
  validateSchema: false
136
138
  });
137
- var validate = ajv.compile(bundleSchema);
138
- function validateBundle(data) {
139
+ var validate = ajv.compile(templateJsonSchema);
140
+ function validateTemplateJson(data) {
139
141
  if (!data || typeof data !== "object" || Array.isArray(data)) {
140
- throw new EngineError("bundle must be a JSON object", "BUNDLE_INVALID" /* BUNDLE_INVALID */);
142
+ throw new EngineError(
143
+ "template.json must be a JSON object",
144
+ "TEMPLATE_JSON_INVALID" /* TEMPLATE_JSON_INVALID */
145
+ );
141
146
  }
142
147
  const valid = validate(data);
143
148
  if (!valid) {
144
149
  const message = formatAjvErrors(validate.errors ?? []);
145
- throw new EngineError(message, "BUNDLE_INVALID" /* BUNDLE_INVALID */);
150
+ throw new EngineError(message, "TEMPLATE_JSON_INVALID" /* TEMPLATE_JSON_INVALID */);
146
151
  }
147
152
  const record = data;
148
- const metadataBlock = record["metadata"];
153
+ const templateBlock = record["template"];
149
154
  const metadata = {
150
- name: metadataBlock["name"],
151
- version: metadataBlock["version"],
152
- ...metadataBlock["description"] !== void 0 ? { description: metadataBlock["description"] } : {}
155
+ name: templateBlock["name"],
156
+ version: templateBlock["version"],
157
+ ...templateBlock["description"] !== void 0 ? { description: templateBlock["description"] } : {}
153
158
  };
154
- const jsonSchema = record["jsonSchema"];
159
+ const jsonSchema = record["schema"];
155
160
  return { metadata, jsonSchema };
156
161
  }
157
162
  function formatAjvErrors(errors) {
158
163
  const first = errors[0];
159
164
  if (!first) {
160
- return "bundle validation failed";
165
+ return "template.json validation failed";
161
166
  }
162
167
  const path = first.instancePath || "";
163
168
  if (first.keyword === "required") {
164
169
  const prop = first.params["missingProperty"];
165
- return `bundle must have a "${prop}" key`;
170
+ return `template.json must have a "${prop}" key`;
166
171
  }
167
172
  if (first.keyword === "type") {
168
173
  const expected = first.params["type"];
169
- return `bundle${path ? ` "${dotPath(path)}"` : ""} must be ${expected}`;
174
+ return `template.json${path ? ` "${dotPath(path)}"` : ""} must be ${expected}`;
170
175
  }
171
- if (first.keyword === "pattern" && path === "/metadata/version") {
172
- return `bundle "metadata.version" must be semver format (x.y.z)`;
176
+ if (first.keyword === "pattern" && path === "/template/version") {
177
+ return `template.json "template.version" must be semver format (x.y.z)`;
173
178
  }
174
- if (first.keyword === "minLength" && path === "/metadata/name") {
175
- return `bundle "metadata.name" must be a non-empty string`;
179
+ if (first.keyword === "minLength" && path === "/template/name") {
180
+ return `template.json "template.name" must be a non-empty string`;
176
181
  }
177
182
  if (first.keyword === "const") {
178
183
  const expected = first.params["allowedValue"];
179
- return `bundle "${dotPath(path)}" must be ${JSON.stringify(expected)}`;
184
+ return `template.json "${dotPath(path)}" must be ${JSON.stringify(expected)}`;
180
185
  }
181
- return `bundle validation failed at ${path || "/"}: ${first.message ?? "unknown error"}`;
186
+ return `template.json validation failed at ${path || "/"}: ${first.message ?? "unknown error"}`;
182
187
  }
183
188
  function dotPath(jsonPointer) {
184
189
  return jsonPointer.replace(/^\//, "").replace(/\//g, ".");
@@ -696,7 +701,7 @@ function computeAggregateHash(files) {
696
701
  }
697
702
 
698
703
  // src/render/manifest.ts
699
- var ENGINE_VERSION = "0.1.3-canary.abfd26a";
704
+ var ENGINE_VERSION = "0.1.3";
700
705
  function generateManifest(opts) {
701
706
  const { files, template, inputs, formatted, intentId, platformPrefix = "tfy_" } = opts;
702
707
  const manifestFiles = [];
@@ -1001,11 +1006,8 @@ var HclEngineImpl = class {
1001
1006
  /**
1002
1007
  * Upgrade: Update an existing cluster to new templates.
1003
1008
  *
1004
- * Pipeline: validate envelope → drift detection (FR-028) → validate inputs
1005
- * render → format → hash + manifest.
1006
- *
1007
- * The engine always renders new files regardless of source mismatch.
1008
- * Callers (CLI/Server) enforce blocking policy via `sourceBlocked` flag (FR-029).
1009
+ * Pipeline: validate envelope → drift detection (FR-028) → if source mismatch,
1010
+ * short-circuit → validate inputs → render → format → hash + manifest.
1009
1011
  */
1010
1012
  async upgrade(envelope, currentFiles, previousManifest) {
1011
1013
  const validatedEnvelope = this.validateEnvelopeOrThrow(envelope);
@@ -1014,6 +1016,14 @@ var HclEngineImpl = class {
1014
1016
  const incomingSource = validatedEnvelope.template.source;
1015
1017
  const driftReport = buildDriftReport(currentFiles, previousManifest, prefix, incomingSource);
1016
1018
  const sourceBlocked = driftReport.summary.sourceMismatches > 0;
1019
+ if (sourceBlocked) {
1020
+ return {
1021
+ files: currentFiles,
1022
+ manifest: previousManifest,
1023
+ driftReport,
1024
+ sourceBlocked: true
1025
+ };
1026
+ }
1017
1027
  const { renderedFiles, template, formatted, inputsWithDefaults } = await this.renderPipeline(
1018
1028
  validatedEnvelope,
1019
1029
  options
@@ -1026,7 +1036,7 @@ var HclEngineImpl = class {
1026
1036
  formatted,
1027
1037
  prefix
1028
1038
  );
1029
- return { files: fileMap, manifest, driftReport, sourceBlocked };
1039
+ return { files: fileMap, manifest, driftReport, sourceBlocked: false };
1030
1040
  }
1031
1041
  /**
1032
1042
  * Verify: Check integrity of existing files against a Manifest.
@@ -1185,14 +1195,14 @@ function createEngine() {
1185
1195
  DEFAULT_PREFIX,
1186
1196
  EngineError,
1187
1197
  EngineErrorCode,
1188
- bundleSchema,
1189
1198
  canonicalHash,
1190
1199
  classifyFile,
1191
1200
  createEngine,
1192
1201
  getCanonicalHashScriptPath,
1193
1202
  isTofuAvailable,
1194
1203
  parseHeader,
1195
- validateBundle,
1196
- validateJsonSchemaStructure
1204
+ templateJsonSchema,
1205
+ validateJsonSchemaStructure,
1206
+ validateTemplateJson
1197
1207
  });
1198
1208
  //# sourceMappingURL=index.js.map