@aifabrix/builder 2.57.0 → 2.59.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 (106) hide show
  1. package/lib/agent-kit/codex-app-server.js +44 -0
  2. package/lib/agent-kit/init.js +4 -17
  3. package/lib/agent-kit/session-report.js +15 -10
  4. package/lib/agent-kit/setup-auth.js +131 -0
  5. package/lib/agent-kit/setup-context.js +118 -0
  6. package/lib/agent-kit/setup-github.js +70 -0
  7. package/lib/agent-kit/setup-managed.js +79 -0
  8. package/lib/agent-kit/setup-process.js +42 -0
  9. package/lib/agent-kit/setup-session.js +53 -0
  10. package/lib/agent-kit/setup-state.js +52 -0
  11. package/lib/agent-kit/setup-workspace.js +113 -0
  12. package/lib/agent-kit/setup.js +84 -0
  13. package/lib/agent-kit/start.js +4 -3
  14. package/lib/agent-kit/tmux-sessions.js +20 -3
  15. package/lib/api/dev.api.js +1 -1
  16. package/lib/api/miso-health.api.js +26 -0
  17. package/lib/api/types/dev.types.js +3 -3
  18. package/lib/app/deploy.js +0 -102
  19. package/lib/app/push.js +98 -41
  20. package/lib/build/standard-docker-build.js +13 -11
  21. package/lib/cli/index.js +4 -0
  22. package/lib/cli/setup-app.js +16 -5
  23. package/lib/cli/setup-dev-path-commands.js +53 -2
  24. package/lib/cli/setup-dev.js +7 -4
  25. package/lib/cli/setup-environment.js +17 -4
  26. package/lib/cli/setup-help.js +86 -0
  27. package/lib/cli/setup-onboarding.js +37 -0
  28. package/lib/cli/setup-utility-repair.js +7 -5
  29. package/lib/commands/agent-kit-help.js +21 -7
  30. package/lib/commands/agent-kit-sessions.js +126 -0
  31. package/lib/commands/agent-kit-setup.js +44 -0
  32. package/lib/commands/agent-kit.js +5 -79
  33. package/lib/commands/dev-init.js +21 -23
  34. package/lib/commands/dev-refresh.js +2 -2
  35. package/lib/commands/dev-registry.js +155 -0
  36. package/lib/commands/dev-show-display.js +10 -2
  37. package/lib/commands/governance-verify-external.js +12 -5
  38. package/lib/commands/repair-datasource.js +9 -9
  39. package/lib/commands/repair.js +45 -8
  40. package/lib/commands/setup-image-refresh.js +26 -0
  41. package/lib/commands/upload-qualification-client.js +56 -11
  42. package/lib/commands/upload-qualification-poll.js +51 -22
  43. package/lib/commands/wizard-dataplane.js +16 -52
  44. package/lib/core/config-attach-extensions.js +4 -1
  45. package/lib/datasource/datasource-validate-summary.js +8 -5
  46. package/lib/datasource/sync-defaults.js +53 -0
  47. package/lib/deployment/installation/azure-infra-stage.js +50 -9
  48. package/lib/deployment/installation/azure-preflight.js +63 -7
  49. package/lib/deployment/installation/azure-readiness.js +59 -7
  50. package/lib/deployment/installation/environment-auth.js +60 -20
  51. package/lib/deployment/installation/environment-stage.js +9 -5
  52. package/lib/deployment/installation/infra-catalog.js +57 -5
  53. package/lib/deployment/installation/infra-manifest.js +22 -2
  54. package/lib/deployment/installation/infra-projection.js +14 -3
  55. package/lib/deployment/installation/registry-auth-mode.js +121 -0
  56. package/lib/deployment/installation/stage-input.js +21 -6
  57. package/lib/deployment/marketplace-environment.js +26 -1
  58. package/lib/generator/builders.js +8 -9
  59. package/lib/generator/index.js +23 -12
  60. package/lib/integration-definition/apply.js +2 -2
  61. package/lib/internal/fs-real-sync.js +4 -1
  62. package/lib/programmatic/bearer-auth.js +3 -62
  63. package/lib/programmatic/builder-api-startup.js +51 -0
  64. package/lib/programmatic/builder-miso-runtime.js +167 -0
  65. package/lib/programmatic/openapi-descriptions.js +3 -3
  66. package/lib/programmatic/openapi-schema-descriptions-core.js +3 -3
  67. package/lib/programmatic/openapi-spec.js +2 -1
  68. package/lib/programmatic/route-handler-map.js +3 -2
  69. package/lib/schema/environment-deploy-request.schema.json +1 -1
  70. package/lib/schema/external-datasource.schema.json +20 -5
  71. package/lib/schema/infra-parameter.schema.json +1 -1
  72. package/lib/schema/infra.parameter.yaml +2 -1
  73. package/lib/schema/infrastructure-schema.json +200 -3
  74. package/lib/schema/installation-environment.schema.json +1 -1
  75. package/lib/schema/wizard-config.schema.json +1 -1
  76. package/lib/utils/app-register-config.js +2 -4
  77. package/lib/utils/build-resolve-image.js +2 -21
  78. package/lib/utils/cli-utils.js +8 -1
  79. package/lib/utils/config-paths.js +24 -29
  80. package/lib/utils/config-registry-preference.js +113 -0
  81. package/lib/utils/dev-init-ssh-merge.js +5 -4
  82. package/lib/utils/dev-user-groups.js +2 -1
  83. package/lib/utils/docker-build.js +53 -19
  84. package/lib/utils/docker-daemon-tls-ca.js +2 -2
  85. package/lib/utils/env-map.js +23 -6
  86. package/lib/utils/error-formatters/validation-errors.js +25 -5
  87. package/lib/utils/help-builder.js +4 -3
  88. package/lib/utils/image-tags.js +88 -0
  89. package/lib/utils/promote-dev-docker-image.js +6 -0
  90. package/lib/utils/registry-credentials.js +236 -0
  91. package/lib/utils/resolve-docker-image-ref.js +78 -9
  92. package/lib/utils/secrets-helpers.js +9 -1
  93. package/lib/utils/token-manager.js +29 -36
  94. package/lib/utils/variable-transformer.js +2 -4
  95. package/package.json +4 -2
  96. package/templates/agent-kit/instructions/AGENTKIT.md +39 -2
  97. package/templates/agent-kit/instructions/root.AGENTS.md +40 -1
  98. package/templates/agent-kit/skills/shared/hosts.md +23 -5
  99. package/templates/agent-kit/workspace/README.md +14 -1
  100. package/templates/applications/builder-api/application.yaml +1 -1
  101. package/templates/applications/dataplane/application.yaml +1 -1
  102. package/templates/applications/dataplane/env.template +1 -1
  103. package/templates/applications/miso-controller/application.yaml +1 -1
  104. package/templates/applications/miso-controller/env.template +1 -1
  105. package/templates/external-system/external-datasource.yaml.hbs +7 -6
  106. package/templates/marketplace/main.json +440 -82
@@ -0,0 +1,51 @@
1
+ /** @fileoverview Await SDK bootstrap and token proof before accepting requests. */
2
+ 'use strict';
3
+
4
+ const { initializeBuilderMisoRuntime, closeBuilderMisoRuntime } = require('./builder-miso-runtime');
5
+ const { ensureBuilderApiRuntimeConfigDir } = require('./builder-api-runtime-config');
6
+
7
+ /** @param {Object} server HTTP server @returns {Promise<void>} Listener closed */
8
+ function closeServer(server) {
9
+ return new Promise(resolve => {
10
+ server.close(resolve);
11
+ server.closeAllConnections();
12
+ });
13
+ }
14
+
15
+ /**
16
+ * @param {Object} [options] Startup dependencies
17
+ * @returns {Promise<{server: Object, close: Function}>} Running application
18
+ */
19
+ async function startBuilderApi(options = {}) {
20
+ ensureBuilderApiRuntimeConfigDir();
21
+ let server;
22
+ let closing;
23
+ const close = () => {
24
+ if (!closing) {
25
+ closing = Promise.all([server ? closeServer(server) : undefined, closeBuilderMisoRuntime()]);
26
+ }
27
+ return closing;
28
+ };
29
+ try {
30
+ const runtime = await initializeBuilderMisoRuntime(options.initSecrets);
31
+ await runtime.health();
32
+ const createServer = options.createServer || require('./builder-api-server').createBuilderApiServer;
33
+ server = createServer(options.port ?? Number(process.env.PORT || 3005));
34
+ await new Promise((resolve, reject) => {
35
+ server.once('error', reject);
36
+ server.once('listening', () => {
37
+ server.removeListener('error', reject); resolve();
38
+ });
39
+ });
40
+ return { server, close };
41
+ } catch (error) {
42
+ await close().catch(() => {});
43
+ // Only our allowlisted health errors can cross the process boundary.
44
+ const failure = new Error('Builder API startup failed: Miso application runtime or authentication unavailable');
45
+ failure.statusCode = 503;
46
+ if (error?.statusCode === 503 && error?.errorType?.startsWith('/Errors/miso_')) throw error;
47
+ throw failure;
48
+ }
49
+ }
50
+
51
+ module.exports = { startBuilderApi };
@@ -0,0 +1,167 @@
1
+ /**
2
+ * Builder's process-owned SDK runtime and application-token health check.
3
+ * @fileoverview SDK owns providers, secrets, renewal and connections.
4
+ */
5
+ 'use strict';
6
+
7
+ const { validateMisoApplicationToken } = require('../api/miso-health.api');
8
+ let activeRuntime;
9
+
10
+ /** @param {string} code Safe category @returns {Error} Service-unavailable error */
11
+ function runtimeError(code) {
12
+ const messages = {
13
+ miso_authentication_failed: 'Miso application authentication failed',
14
+ miso_timeout: 'Miso application token check timed out',
15
+ miso_unreachable: 'Miso Controller is unavailable',
16
+ miso_runtime_unavailable: 'Miso application runtime is unavailable'
17
+ };
18
+ return Object.assign(new Error(messages[code]), {
19
+ statusCode: 503, code, errorType: `/Errors/${code}`
20
+ });
21
+ }
22
+
23
+ /** @param {unknown} error SDK error @returns {string} Safe category */
24
+ function failureCode(error) {
25
+ const status = error?.statusCode || error?.errorResponse?.status || error?.response?.status;
26
+ if ([401, 403].includes(status) || error?.code === 'authorization-denied') {
27
+ return 'miso_authentication_failed';
28
+ }
29
+ if (['ECONNABORTED', 'ETIMEDOUT', 'ERR_CANCELED'].includes(error?.code)) {
30
+ return 'miso_timeout';
31
+ }
32
+ return 'miso_unreachable';
33
+ }
34
+
35
+ /** SDK resource ownership and fail-closed application state. */
36
+ class RuntimeController {
37
+ /** @param {Object} runtime SDK runtime */
38
+ constructor(runtime) {
39
+ this.runtime = runtime;
40
+ this.unsubscribe = runtime.onInvalidated(reason => {
41
+ this.unavailable = reason === 'authorization-denied'
42
+ ? 'miso_authentication_failed' : 'miso_runtime_unavailable';
43
+ this.abort?.abort();
44
+ });
45
+ }
46
+
47
+ /** @returns {void} Throws when the SDK snapshot is unavailable */
48
+ assertAvailable() {
49
+ if (this.unavailable) throw runtimeError(this.unavailable);
50
+ try {
51
+ this.runtime.secrets.get('');
52
+ } catch {
53
+ throw runtimeError(this.unavailable || 'miso_runtime_unavailable');
54
+ }
55
+ }
56
+
57
+ /** @returns {Object} Initialized client */
58
+ getClient() {
59
+ this.assertAvailable();
60
+ return this.runtime.client;
61
+ }
62
+
63
+ /** @returns {Promise<void>} Idempotent cleanup */
64
+ close() {
65
+ if (!this.closing) {
66
+ this.unavailable = this.unavailable || 'miso_runtime_unavailable';
67
+ this.abort?.abort();
68
+ this.unsubscribe();
69
+ this.closing = Promise.resolve().then(() => this.runtime.close()).catch(() => {
70
+ throw runtimeError('miso_runtime_unavailable');
71
+ });
72
+ }
73
+ return this.closing;
74
+ }
75
+
76
+ /** @returns {Promise<void>} Fresh, coalesced token proof; never caches success */
77
+ health() {
78
+ this.assertAvailable();
79
+ if (!this.pending) {
80
+ this.abort = new AbortController();
81
+ this.pending = runProbe(this.runtime.client, this.abort,
82
+ () => this.assertAvailable(), code => {
83
+ this.unavailable = code;
84
+ void this.close().catch(() => {});
85
+ }, () => {
86
+ this.pending = undefined;
87
+ });
88
+ }
89
+ return this.pending;
90
+ }
91
+ }
92
+
93
+ /** @param {Object} runtime SDK runtime @returns {RuntimeController} Consumer controls */
94
+ function createRuntimeController(runtime) {
95
+ return new RuntimeController(runtime);
96
+ }
97
+
98
+ /**
99
+ * Coalesce until transport settles, including SDK-owned token acquisition after a deadline.
100
+ * @param {Object} client SDK client
101
+ * @param {AbortController} abort Cancellation
102
+ * @param {Function} assertAvailable Runtime guard
103
+ * @param {Function} invalidate Terminal rejection
104
+ * @param {Function} settled Release in-flight work
105
+ * @returns {Promise<void>} Bounded health result
106
+ */
107
+ function runProbe(client, abort, assertAvailable, invalidate, settled) {
108
+ let timer;
109
+ const deadline = new Promise((_, reject) => {
110
+ timer = setTimeout(() => {
111
+ abort.abort(); reject(runtimeError('miso_timeout'));
112
+ }, 3000);
113
+ });
114
+ const request = validateMisoApplicationToken(client, abort.signal).then(() => {
115
+ assertAvailable();
116
+ }).catch(error => {
117
+ let code = failureCode(error);
118
+ try {
119
+ assertAvailable();
120
+ } catch (unavailable) {
121
+ code = unavailable.code;
122
+ }
123
+ if (code === 'miso_authentication_failed') invalidate(code);
124
+ throw runtimeError(code);
125
+ }).finally(() => {
126
+ clearTimeout(timer); settled();
127
+ });
128
+ return Promise.race([request, deadline]);
129
+ }
130
+
131
+ /** @param {Function} [init] SDK factory for tests @returns {Promise<Object>} Runtime controls */
132
+ async function initializeBuilderMisoRuntime(init) {
133
+ if (activeRuntime) throw runtimeError('miso_runtime_unavailable');
134
+ const factory = init || require('@aifabrix/miso-client/bootstrap').initSecrets;
135
+ try {
136
+ activeRuntime = createRuntimeController(await factory());
137
+ return activeRuntime;
138
+ } catch {
139
+ throw runtimeError('miso_runtime_unavailable');
140
+ }
141
+ }
142
+
143
+ /** @returns {Object} Active guarded runtime */
144
+ function getBuilderMisoRuntime() {
145
+ if (!activeRuntime) throw runtimeError('miso_runtime_unavailable');
146
+ return activeRuntime;
147
+ }
148
+
149
+ /** @returns {Promise<void>} Close and release process-owned runtime */
150
+ async function closeBuilderMisoRuntime() {
151
+ const current = activeRuntime;
152
+ activeRuntime = undefined;
153
+ await current?.close();
154
+ }
155
+
156
+ /** @param {boolean} [ready] Readiness response @returns {Promise<Object>} Healthy payload */
157
+ async function checkBuilderMisoHealth(ready = false) {
158
+ await getBuilderMisoRuntime().health();
159
+ return ready
160
+ ? { status: 'ready', dataplaneUrl: process.env.DATAPLANE_URL || null }
161
+ : { status: 'ok' };
162
+ }
163
+
164
+ module.exports = {
165
+ initializeBuilderMisoRuntime, getBuilderMisoRuntime, closeBuilderMisoRuntime,
166
+ checkBuilderMisoHealth, createRuntimeController
167
+ };
@@ -213,14 +213,14 @@ const OPERATION_DESCRIPTIONS = Object.freeze({
213
213
  tags: ['repository']
214
214
  },
215
215
  health: {
216
- summary: 'Liveness probe',
216
+ summary: 'Application-token health probe',
217
217
  description:
218
- 'Returns ok when the builder-api process is running. Portal availability probe. Empty channel catalog is not a down signal. No authentication.',
218
+ 'Returns ok only after Miso accepts the application client token. Returns 503 when authentication, runtime validity or connectivity fails. No caller authentication; user credentials cannot substitute for the application token.',
219
219
  tags: ['infra']
220
220
  },
221
221
  ready: {
222
222
  summary: 'Readiness probe',
223
- description: 'Returns ready with configured dataplaneUrl. Does not verify Dataplane connectivity in V1.',
223
+ description: 'Verifies the application client token with Miso and returns ready with configured dataplaneUrl. Returns 503 for an unusable token or unavailable Miso runtime. Does not verify Dataplane connectivity.',
224
224
  tags: ['infra']
225
225
  },
226
226
  getBuilderHelp: {
@@ -113,11 +113,11 @@ const CORE_SCHEMA_DESCRIPTIONS = {
113
113
  deleted: 'Always true when the workspace folder was removed.'
114
114
  },
115
115
  HealthData: {
116
- _schema: 'Liveness probe payload when the builder-api process is running.',
117
- status: 'Always ok for successful liveness checks.'
116
+ _schema: 'Health payload after Miso accepts the application client token.',
117
+ status: 'Always ok after successful application-token validation.'
118
118
  },
119
119
  ReadyData: {
120
- _schema: 'Readiness probe payload; does not verify Dataplane connectivity in V1.',
120
+ _schema: 'Readiness after Miso application-token validation; does not verify Dataplane connectivity.',
121
121
  status: 'Always ready when the service accepts traffic.',
122
122
  dataplaneUrl: 'Configured dev Dataplane base URL, or null when unset.'
123
123
  },
@@ -68,7 +68,8 @@ function buildStandardErrorResponses() {
68
68
  408: problemResponseContent('Request exceeded capability timeout.'),
69
69
  409: problemResponseContent('Workspace lock held by another in-flight operation.'),
70
70
  413: problemResponseContent('Request body exceeds MAX_BODY_BYTES.'),
71
- 500: problemResponseContent('Unexpected server error.')
71
+ 500: problemResponseContent('Unexpected server error.'),
72
+ 503: problemResponseContent('Miso application authentication failed, token check timed out, or runtime/Controller unavailable. Safe failure category appears in type.')
72
73
  };
73
74
  }
74
75
 
@@ -8,6 +8,7 @@
8
8
 
9
9
  'use strict';
10
10
 
11
+ const { checkBuilderMisoHealth } = require('./builder-miso-runtime');
11
12
  const { buildContext } = require('./route-handlers-context');
12
13
  const { listSystems, createSystem, getSystemManifest, deleteSystem } = require('./workspace-ops');
13
14
  const { persistSuppliedOpenApi } = require('./persist-supplied-openapi');
@@ -230,8 +231,8 @@ const HANDLER_MAP = {
230
231
  getRepositoryStatus: (params, auth) => getRepositoryStatus(buildContext(auth, params.systemKey)),
231
232
  runRepositoryDispatchPipeline: (params, auth, body) =>
232
233
  runRepositoryDispatchPipeline(buildContext(auth, params.systemKey), body),
233
- health: () => ({ status: 'ok' }),
234
- ready: () => ({ status: 'ready', dataplaneUrl: process.env.DATAPLANE_URL || null }),
234
+ health: () => checkBuilderMisoHealth(),
235
+ ready: () => checkBuilderMisoHealth(true),
235
236
  getBuilderHelp: (_params, _auth, _body, query) => handleGetBuilderHelp(query || {}),
236
237
  getEvidenceMetadata: (params, auth) =>
237
238
  getEvidenceMetadata(buildContext(auth, '_evidence'), params.roleKey),
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "http://json-schema.org/draft-07/schema#",
3
- "$id": "https://raw.githubusercontent.com/esystemsdev/aifabrix-builder/refs/heads/main/lib/schema/environment-deploy-request.schema.json",
3
+ "$id": "aifabrix://schema/environment-deploy-request.schema.json",
4
4
  "title": "Environment Deploy Request",
5
5
  "description": "Request body for POST /api/v1/environments/{envKey}/deploy",
6
6
  "type": "object",
@@ -7,12 +7,12 @@
7
7
  "key":"external-datasource-schema",
8
8
  "name":"External Data Source Configuration Schema",
9
9
  "description":"JSON schema for validating ExternalDataSource configuration files",
10
- "version":"2.9.11",
10
+ "version":"2.9.12",
11
11
  "type":"schema",
12
12
  "category":"integration",
13
13
  "author":"AI Fabrix Team",
14
14
  "createdAt":"2024-01-01T00:00:00Z",
15
- "updatedAt":"2026-08-30T00:00:00Z",
15
+ "updatedAt":"2026-09-17T00:00:00Z",
16
16
  "compatibility":{
17
17
  "minVersion":"1.0.0",
18
18
  "maxVersion":"3.0.0",
@@ -31,6 +31,15 @@
31
31
  "external-system.schema.json"
32
32
  ],
33
33
  "changelog":[
34
+ {
35
+ "version":"2.9.12",
36
+ "date":"2026-09-17T00:00:00Z",
37
+ "changes":[
38
+ "Added cipOperation.shape enum value 'upsert' (manifest-declared only; composes the datasource's standard create + update via fetch.source datasource; existence-resolved branch with fail-closed per-action permissions). COM writeShape and published x-ai-intent gain the same value. 543 O-SHAPE updated.",
39
+ "Added optional sync.enabled (default true) to disable scheduled, manual, webhook, and syncBridge synchronization without disabling datasource reads. Added @monthly as the authoring default for new full-set schedules; existing schedule-less manifests remain valid and are not migrated. CIP $defs unchanged (543 visual N/A)."
40
+ ],
41
+ "breaking":false
42
+ },
34
43
  {
35
44
  "version":"2.9.11",
36
45
  "date":"2026-08-30T00:00:00Z",
@@ -862,6 +871,11 @@
862
871
  "type":"object",
863
872
  "description":"Record synchronization rules.",
864
873
  "properties":{
874
+ "enabled":{
875
+ "type":"boolean",
876
+ "description":"Whether synchronization is enabled for this datasource. False blocks scheduled, manual, webhook, and syncBridge synchronization while preserving normal datasource access.",
877
+ "default":true
878
+ },
865
879
  "mode":{
866
880
  "type":"string",
867
881
  "enum":[
@@ -874,6 +888,7 @@
874
888
  "schedule":{
875
889
  "type":"string",
876
890
  "description":"Cron for full-set (sync all) jobs. Supports 5-field cron syntax or @hourly/@daily/@weekly/@monthly.",
891
+ "default":"@monthly",
877
892
  "pattern":"^(@hourly|@daily|@weekly|@monthly|([0-9*/,-]+\\s+){4}[0-9*/,-]+)$"
878
893
  },
879
894
  "batchSize":{
@@ -2547,9 +2562,10 @@
2547
2562
  "enum":[
2548
2563
  "create",
2549
2564
  "update",
2550
- "delete"
2565
+ "delete",
2566
+ "upsert"
2551
2567
  ],
2552
- "description":"Manifest classification for custom operations when fetch step inference is insufficient. Resolved by resolve_cip_write_shape (precedence over fetch inference) and drives x-ai-intent, x-ai-sideEffects, and x-ai-contract.riskLevel on published OpenAPI. shape delete marks the operation as dangerous for agent policy (with core capability delete)."
2568
+ "description":"Manifest classification for custom operations when fetch step inference is insufficient. Resolved by resolve_cip_write_shape (precedence over fetch inference) and drives x-ai-intent, x-ai-sideEffects, and x-ai-contract.riskLevel on published OpenAPI. shape delete marks the operation as dangerous for agent policy (with core capability delete). shape upsert is never inferred: the operation must compose exactly this datasource's standard create and update operations as two fetch.source 'datasource' steps; at execution the generic CIP branch resolves record existence from validation.repeatingValues reject fields and runs exactly one half, enforcing that half's permissions fail-closed (no cross-action fallback)."
2553
2569
  },
2554
2570
  "steps":{
2555
2571
  "type":"array",
@@ -3467,4 +3483,3 @@
3467
3483
  },
3468
3484
  "additionalProperties":false
3469
3485
  }
3470
-
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "http://json-schema.org/draft-07/schema#",
3
- "$id": "https://aifabrix.dev/schemas/infra-parameter.schema.json",
3
+ "$id": "aifabrix://schema/infra-parameter.schema.json",
4
4
  "title": "Infra parameter catalog",
5
5
  "type": "object",
6
6
  "required": ["version", "parameters"],
@@ -98,7 +98,8 @@ parameters:
98
98
  category: Redis
99
99
  sensitive: true
100
100
  valueSource: providerOutput
101
- requiredOnSystemOnboarding: true
101
+ # Not needed at first-time install: Redis is provisioned later (env deploy / TA), not at marketplace bootstrap.
102
+ requiredOnSystemOnboarding: false
102
103
  scope: system
103
104
  generator:
104
105
  type: literal
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "http://json-schema.org/draft-07/schema#",
3
- "$id": "https://raw.githubusercontent.com/esystemsdev/aifabrix-builder/refs/heads/main/lib/schema/infrastructure-schema.json",
3
+ "$id": "aifabrix://schema/infrastructure-schema.json",
4
4
  "title": "AI Fabrix Installation Infrastructure Manifest",
5
5
  "description": "Committed, non-secret environment-infra.json for an installation workspace under infrastructure/<resource-group>/. Secrets appear only as valueFromEnv references.",
6
6
  "metadata": {
@@ -12,7 +12,7 @@
12
12
  "category": "infrastructure",
13
13
  "author": "AI Fabrix Team",
14
14
  "createdAt": "2024-01-01T00:00:00Z",
15
- "updatedAt": "2026-09-16T00:00:00Z",
15
+ "updatedAt": "2026-09-17T00:00:00Z",
16
16
  "compatibility": {
17
17
  "minVersion": "2.0.0",
18
18
  "maxVersion": "2.0.0",
@@ -34,7 +34,7 @@
34
34
  "Replaced the environment-configuration shape with the installation workspace manifest (environment-infra.json).",
35
35
  "Removed smtp without replacement.",
36
36
  "Covers every Marketplace template parameter and output with source/description metadata; secure parameters are valueFromEnv references.",
37
- "Added vendor, workspace subscription/tenant, acrName, default-off allowMyIp, licenseEdition, onboardingMode, tenant activation, deployment and application variable catalog sections."
37
+ "Added vendor, workspace subscription/tenant, acrName, acrAuth (auto|mi|credentials, deprecated admin alias, resolved effective mode), deployRoleAssignments restore metadata, default-off allowMyIp, licenseEdition, onboardingMode, tenant activation, deployment and application variable catalog sections."
38
38
  ]
39
39
  },
40
40
  {
@@ -366,6 +366,44 @@
366
366
  }
367
367
  }
368
368
  },
369
+ "acrAuth": {
370
+ "type": "object",
371
+ "required": [
372
+ "value",
373
+ "source",
374
+ "description"
375
+ ],
376
+ "additionalProperties": false,
377
+ "properties": {
378
+ "value": {
379
+ "enum": [
380
+ "auto",
381
+ "mi",
382
+ "credentials",
383
+ "admin"
384
+ ],
385
+ "description": "Requested image-pull auth; admin is a deprecated alias for credentials."
386
+ },
387
+ "source": {
388
+ "type": "string",
389
+ "minLength": 1
390
+ },
391
+ "description": {
392
+ "type": "string",
393
+ "minLength": 1
394
+ },
395
+ "required": {
396
+ "type": "boolean"
397
+ },
398
+ "effective": {
399
+ "enum": [
400
+ "mi",
401
+ "credentials"
402
+ ],
403
+ "description": "Pull auth resolved by the last infra run (non-secret)."
404
+ }
405
+ }
406
+ },
369
407
  "allowMyIp": {
370
408
  "type": "object",
371
409
  "required": [
@@ -469,6 +507,7 @@
469
507
  "entraIdClientSecret",
470
508
  "entraIdTenantId",
471
509
  "licenseEdition",
510
+ "capacityProfile",
472
511
  "onboardingMode",
473
512
  "misoImageTag",
474
513
  "keycloakImageTag"
@@ -926,6 +965,65 @@
926
965
  },
927
966
  "required": {
928
967
  "type": "boolean"
968
+ },
969
+ "restoreValue": {
970
+ "type": [
971
+ "string",
972
+ "boolean",
973
+ "number",
974
+ "object",
975
+ "array"
976
+ ],
977
+ "description": "Value to restore when credential mode no longer applies."
978
+ },
979
+ "restoreSource": {
980
+ "type": "string",
981
+ "minLength": 1
982
+ }
983
+ }
984
+ },
985
+ "deployRegistryRoleAssignment": {
986
+ "type": "object",
987
+ "required": [
988
+ "value",
989
+ "source",
990
+ "description"
991
+ ],
992
+ "additionalProperties": false,
993
+ "properties": {
994
+ "value": {
995
+ "type": [
996
+ "string",
997
+ "boolean",
998
+ "number",
999
+ "object",
1000
+ "array"
1001
+ ]
1002
+ },
1003
+ "source": {
1004
+ "type": "string",
1005
+ "minLength": 1
1006
+ },
1007
+ "description": {
1008
+ "type": "string",
1009
+ "minLength": 1
1010
+ },
1011
+ "required": {
1012
+ "type": "boolean"
1013
+ },
1014
+ "restoreValue": {
1015
+ "type": [
1016
+ "string",
1017
+ "boolean",
1018
+ "number",
1019
+ "object",
1020
+ "array"
1021
+ ],
1022
+ "description": "Value to restore when credential mode no longer applies."
1023
+ },
1024
+ "restoreSource": {
1025
+ "type": "string",
1026
+ "minLength": 1
929
1027
  }
930
1028
  }
931
1029
  },
@@ -1190,6 +1288,98 @@
1190
1288
  "type": "boolean"
1191
1289
  }
1192
1290
  }
1291
+ },
1292
+ "moriLicensePublicKey": {
1293
+ "type": "object",
1294
+ "required": [
1295
+ "value",
1296
+ "source",
1297
+ "description"
1298
+ ],
1299
+ "additionalProperties": false,
1300
+ "properties": {
1301
+ "value": {
1302
+ "type": [
1303
+ "string",
1304
+ "boolean",
1305
+ "number",
1306
+ "object",
1307
+ "array"
1308
+ ]
1309
+ },
1310
+ "source": {
1311
+ "type": "string",
1312
+ "minLength": 1
1313
+ },
1314
+ "description": {
1315
+ "type": "string",
1316
+ "minLength": 1
1317
+ },
1318
+ "required": {
1319
+ "type": "boolean"
1320
+ }
1321
+ }
1322
+ },
1323
+ "moriLicenseIssuer": {
1324
+ "type": "object",
1325
+ "required": [
1326
+ "value",
1327
+ "source",
1328
+ "description"
1329
+ ],
1330
+ "additionalProperties": false,
1331
+ "properties": {
1332
+ "value": {
1333
+ "type": [
1334
+ "string",
1335
+ "boolean",
1336
+ "number",
1337
+ "object",
1338
+ "array"
1339
+ ]
1340
+ },
1341
+ "source": {
1342
+ "type": "string",
1343
+ "minLength": 1
1344
+ },
1345
+ "description": {
1346
+ "type": "string",
1347
+ "minLength": 1
1348
+ },
1349
+ "required": {
1350
+ "type": "boolean"
1351
+ }
1352
+ }
1353
+ },
1354
+ "capacityProfile": {
1355
+ "type": "object",
1356
+ "required": [
1357
+ "value",
1358
+ "source",
1359
+ "description"
1360
+ ],
1361
+ "additionalProperties": false,
1362
+ "properties": {
1363
+ "value": {
1364
+ "enum": [
1365
+ "s",
1366
+ "m",
1367
+ "l",
1368
+ "xl"
1369
+ ]
1370
+ },
1371
+ "source": {
1372
+ "type": "string",
1373
+ "minLength": 1
1374
+ },
1375
+ "description": {
1376
+ "type": "string",
1377
+ "minLength": 1
1378
+ },
1379
+ "required": {
1380
+ "type": "boolean"
1381
+ }
1382
+ }
1193
1383
  }
1194
1384
  }
1195
1385
  },
@@ -1274,6 +1464,12 @@
1274
1464
  },
1275
1465
  "portalUrl": {
1276
1466
  "$ref": "#/definitions/output"
1467
+ },
1468
+ "azureOpenAiCreated": {
1469
+ "$ref": "#/definitions/output"
1470
+ },
1471
+ "azureOpenAiSkipReason": {
1472
+ "$ref": "#/definitions/output"
1277
1473
  }
1278
1474
  }
1279
1475
  },
@@ -1611,6 +1807,7 @@
1611
1807
  "then": {
1612
1808
  "required": [
1613
1809
  "acrName",
1810
+ "acrAuth",
1614
1811
  "allowMyIp",
1615
1812
  "preset",
1616
1813
  "parameters",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "http://json-schema.org/draft-07/schema#",
3
- "$id": "https://raw.githubusercontent.com/esystemsdev/aifabrix-builder/refs/heads/main/lib/schema/installation-environment.schema.json",
3
+ "$id": "aifabrix://schema/installation-environment.schema.json",
4
4
  "title": "AI Fabrix Installation Environment File",
5
5
  "description": "Committed, non-secret infrastructure/<resource-group>/environment-dev|tst|pro.json. Inherited shared values name environment-infra.json as their source; request is the exact non-secret Miso deploy projection.",
6
6
  "metadata": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "http://json-schema.org/draft-07/schema#",
3
- "$id": "https://raw.githubusercontent.com/esystemsdev/aifabrix-builder/refs/heads/main/lib/schema/wizard-config.schema.json",
3
+ "$id": "aifabrix://schema/wizard-config.schema.json",
4
4
  "title": "AI Fabrix Wizard Configuration Schema",
5
5
  "description": "Schema for validating wizard.yaml configuration files for headless external system creation",
6
6
  "type": "object",