@truefoundry/tfy-infra-engine 0.1.3 → 0.1.4-canary.595d398

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