@aipt/idp-deploy 0.1.2

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 (52) hide show
  1. package/README.md +471 -0
  2. package/bin/idpctl.mjs +8 -0
  3. package/compose/edge.yaml +61 -0
  4. package/compose/flow.yaml +34 -0
  5. package/compose/portal.yaml +38 -0
  6. package/compose/postgresql.yaml +62 -0
  7. package/compose/registry.yaml +35 -0
  8. package/compose/smartgo.yaml +271 -0
  9. package/compose/tech.yaml +64 -0
  10. package/contracts/active-profile.schema.json +19 -0
  11. package/contracts/asset-lifecycle.schema.json +49 -0
  12. package/contracts/backup-generation.schema.json +60 -0
  13. package/contracts/component-runtime.schema.json +32 -0
  14. package/contracts/config-release.schema.json +33 -0
  15. package/contracts/deployment-evidence.schema.json +43 -0
  16. package/contracts/deployment-plan.schema.json +67 -0
  17. package/contracts/release-candidate.schema.json +33 -0
  18. package/contracts/release-defaults.schema.json +56 -0
  19. package/contracts/restore-candidate.schema.json +63 -0
  20. package/contracts/smartgo-component-config.schema.json +79 -0
  21. package/contracts/tech-backup-boundary.schema.json +61 -0
  22. package/contracts/tech-source-credentials.schema.json +17 -0
  23. package/deploy.sh +5 -0
  24. package/docs/restore-runbook.md +56 -0
  25. package/governance/asset-lifecycle.v1.json +79 -0
  26. package/package.json +42 -0
  27. package/release/defaults.v1.json +64 -0
  28. package/src/acceptance.mjs +127 -0
  29. package/src/bindings.mjs +518 -0
  30. package/src/cli.mjs +360 -0
  31. package/src/compose.mjs +19 -0
  32. package/src/config.mjs +903 -0
  33. package/src/delivery.mjs +123 -0
  34. package/src/errors.mjs +12 -0
  35. package/src/foundation-contracts.mjs +128 -0
  36. package/src/foundation.mjs +107 -0
  37. package/src/gitops.mjs +285 -0
  38. package/src/hash.mjs +47 -0
  39. package/src/image-lock.mjs +160 -0
  40. package/src/images.mjs +215 -0
  41. package/src/lifecycle.mjs +58 -0
  42. package/src/local-source.mjs +354 -0
  43. package/src/oci-mirror.mjs +10 -0
  44. package/src/operations.mjs +1484 -0
  45. package/src/process.mjs +46 -0
  46. package/src/profiles.mjs +41 -0
  47. package/src/release.mjs +1760 -0
  48. package/src/render.mjs +330 -0
  49. package/src/security.mjs +156 -0
  50. package/src/source-contracts.mjs +106 -0
  51. package/src/sources.mjs +78 -0
  52. package/src/workbench-projects.mjs +118 -0
@@ -0,0 +1,62 @@
1
+ services:
2
+ postgresql:
3
+ image: ${IDP_POSTGRES_IMAGE}
4
+ platform: ${IDP_RUNTIME_PLATFORM}
5
+ restart: unless-stopped
6
+ environment:
7
+ POSTGRES_USER: postgres
8
+ POSTGRES_PASSWORD_FILE: /run/secrets/postgresql-superuser-password
9
+ POSTGRES_INITDB_ARGS: --encoding=UTF8 --auth-host=scram-sha-256 --auth-local=peer
10
+ secrets:
11
+ - postgresql-superuser-password
12
+ volumes:
13
+ - ${IDP_DATA_DIR}/postgresql:/var/lib/postgresql/data
14
+ networks:
15
+ - idp_backend
16
+ healthcheck:
17
+ test: [CMD-SHELL, pg_isready --username postgres --dbname postgres]
18
+ interval: 10s
19
+ timeout: 5s
20
+ retries: 12
21
+ start_period: 20s
22
+ stop_grace_period: 60s
23
+ shm_size: 256mb
24
+ security_opt:
25
+ - no-new-privileges:true
26
+
27
+ postgresql-bootstrap:
28
+ image: ${IDP_POSTGRES_IMAGE}
29
+ platform: ${IDP_RUNTIME_PLATFORM}
30
+ restart: "no"
31
+ user: ${IDP_CONTAINER_UID}:${IDP_CONTAINER_GID}
32
+ environment:
33
+ POSTGRES_USER: postgres
34
+ PGHOST: postgresql
35
+ PGPASSWORD_FILE: /run/idp-secrets/superuser-password
36
+ POSTGRES_TECH_PASSWORD_FILE: /run/idp-secrets/tech-password
37
+ POSTGRES_PORTAL_PASSWORD_FILE: /run/idp-secrets/portal-password
38
+ POSTGRES_SMARTGO_PASSWORD_FILE: /run/idp-secrets/smartgo-password
39
+ command: [/docker-entrypoint-initdb.d/010-create-databases.sh]
40
+ volumes:
41
+ - ../scripts/postgresql/010-create-databases.sh:/docker-entrypoint-initdb.d/010-create-databases.sh:ro
42
+ - ${IDP_RENDER_DIR}/postgresql-bootstrap:/run/idp-secrets:ro
43
+ networks:
44
+ - idp_backend
45
+ depends_on:
46
+ postgresql:
47
+ condition: service_healthy
48
+ read_only: true
49
+ tmpfs:
50
+ - /tmp:size=32m,mode=1777
51
+ cap_drop:
52
+ - ALL
53
+ security_opt:
54
+ - no-new-privileges:true
55
+
56
+ secrets:
57
+ postgresql-superuser-password:
58
+ file: ${IDP_CONFIG_DIR}/${IDP_POSTGRES_SUPERUSER_PASSWORD_FILE}
59
+
60
+ networks:
61
+ idp_backend:
62
+ internal: true
@@ -0,0 +1,35 @@
1
+ services:
2
+ registry:
3
+ image: ${IDP_REGISTRY_IMAGE}
4
+ platform: ${IDP_RUNTIME_PLATFORM}
5
+ restart: unless-stopped
6
+ user: ${IDP_CONTAINER_UID}:${IDP_CONTAINER_GID}
7
+ environment:
8
+ VERDACCIO_PORT: "4873"
9
+ ports:
10
+ - target: 4873
11
+ published: "${IDP_REGISTRY_PORT}"
12
+ host_ip: ${IDP_REGISTRY_BIND}
13
+ protocol: tcp
14
+ volumes:
15
+ - ${IDP_RENDER_DIR}/registry:/verdaccio/conf:ro
16
+ - ${IDP_DATA_DIR}/registry:/verdaccio/storage
17
+ networks:
18
+ - idp_egress
19
+ healthcheck:
20
+ test: [CMD, node, -e, "fetch('http://127.0.0.1:4873/-/ping').then(r=>{if(!r.ok)process.exit(1)}).catch(()=>process.exit(1))"]
21
+ interval: 10s
22
+ timeout: 5s
23
+ retries: 12
24
+ start_period: 20s
25
+ read_only: true
26
+ tmpfs:
27
+ - /tmp:size=64m,mode=1777
28
+ init: true
29
+ cap_drop:
30
+ - ALL
31
+ security_opt:
32
+ - no-new-privileges:true
33
+
34
+ networks:
35
+ idp_egress: {}
@@ -0,0 +1,271 @@
1
+ x-smartgo-runtime: &smartgo-runtime
2
+ image: ${IDP_SMARTGO_IMAGE}
3
+ platform: ${IDP_RUNTIME_PLATFORM}
4
+ restart: unless-stopped
5
+ user: ${IDP_CONTAINER_UID}:${IDP_CONTAINER_GID}
6
+ working_dir: /workspace
7
+ environment:
8
+ IDP_COMPONENT_CONFIG_DIR: /run/idp-config
9
+ volumes:
10
+ - ${IDP_RENDER_DIR}/smartgo:/run/idp-config:ro
11
+ networks:
12
+ - idp_backend
13
+ - idp_egress
14
+ read_only: true
15
+ tmpfs:
16
+ - /tmp:size=256m,mode=1777
17
+ init: true
18
+ cap_drop:
19
+ - ALL
20
+ security_opt:
21
+ - no-new-privileges:true
22
+
23
+ x-smartgo-health: &smartgo-health
24
+ interval: 15s
25
+ timeout: 5s
26
+ retries: 12
27
+ start_period: 45s
28
+
29
+ x-smartgo-component-env: &smartgo-component-env
30
+ IDP_COMPONENT_CONFIG_DIR: /run/idp-config
31
+ SMARTGO_FIXTURE_ONLY: "true"
32
+ SMARTGO_ALLOW_FIXTURE_AUTH: "true"
33
+
34
+ services:
35
+ edge:
36
+ ports:
37
+ - target: ${IDP_SMARTGO_GOTOLOGY_PORT}
38
+ published: "${IDP_SMARTGO_GOTOLOGY_PORT}"
39
+ host_ip: ${IDP_HTTP_BIND}
40
+ protocol: tcp
41
+ - target: ${IDP_SMARTGO_OPERATIONS_PORT}
42
+ published: "${IDP_SMARTGO_OPERATIONS_PORT}"
43
+ host_ip: ${IDP_HTTP_BIND}
44
+ protocol: tcp
45
+ - target: ${IDP_SMARTGO_STUDIO_PORT}
46
+ published: "${IDP_SMARTGO_STUDIO_PORT}"
47
+ host_ip: ${IDP_HTTP_BIND}
48
+ protocol: tcp
49
+
50
+ smartgo-object-store:
51
+ image: ${IDP_SMARTGO_OBJECT_STORE_IMAGE}
52
+ platform: ${IDP_RUNTIME_PLATFORM}
53
+ restart: unless-stopped
54
+ user: ${IDP_CONTAINER_UID}:${IDP_CONTAINER_GID}
55
+ command: [server, /data, --console-address, :9001]
56
+ environment:
57
+ MINIO_ROOT_USER_FILE: /run/idp-config/secrets/minio-root-user
58
+ MINIO_ROOT_PASSWORD_FILE: /run/idp-config/secrets/minio-root-password
59
+ volumes:
60
+ - ${IDP_RENDER_DIR}/smartgo:/run/idp-config:ro
61
+ - ${IDP_DATA_DIR}/smartgo/object-store:/data
62
+ expose:
63
+ - "9000"
64
+ networks:
65
+ - idp_backend
66
+ healthcheck:
67
+ test: [CMD, curl, --fail, --silent, http://127.0.0.1:9000/minio/health/live]
68
+ <<: *smartgo-health
69
+ start_period: 20s
70
+ read_only: true
71
+ tmpfs:
72
+ - /tmp:size=64m,mode=1777
73
+ cap_drop:
74
+ - ALL
75
+ security_opt:
76
+ - no-new-privileges:true
77
+
78
+ smartgo-object-store-init:
79
+ image: ${IDP_SMARTGO_OBJECT_STORE_CLIENT_IMAGE}
80
+ platform: ${IDP_RUNTIME_PLATFORM}
81
+ restart: "no"
82
+ user: ${IDP_CONTAINER_UID}:${IDP_CONTAINER_GID}
83
+ entrypoint: [/bin/sh, -ec]
84
+ environment:
85
+ MC_CONFIG_DIR: /tmp/.mc
86
+ command:
87
+ - |
88
+ access_key="$$(tr -d '\r\n' < /run/idp-config/secrets/minio-root-user)"
89
+ secret_key="$$(tr -d '\r\n' < /run/idp-config/secrets/minio-root-password)"
90
+ mc alias set local http://smartgo-object-store:9000 "$$access_key" "$$secret_key"
91
+ mc mb --ignore-existing local/smartgo-artifacts
92
+ mc anonymous set none local/smartgo-artifacts
93
+ unset access_key secret_key
94
+ volumes:
95
+ - ${IDP_RENDER_DIR}/smartgo:/run/idp-config:ro
96
+ networks:
97
+ - idp_backend
98
+ depends_on:
99
+ smartgo-object-store:
100
+ condition: service_healthy
101
+ read_only: true
102
+ tmpfs:
103
+ - /tmp:size=32m,mode=1777
104
+ cap_drop:
105
+ - ALL
106
+ security_opt:
107
+ - no-new-privileges:true
108
+
109
+ smartgo-migrate:
110
+ <<: *smartgo-runtime
111
+ restart: "no"
112
+ command:
113
+ - sh
114
+ - -c
115
+ - ./packages/persistence/node_modules/.bin/prisma migrate deploy --schema packages/persistence/prisma/schema.prisma && ./packages/persistence/node_modules/.bin/tsx packages/persistence/prisma/bootstrap-reference-catalog.ts && ./packages/persistence/node_modules/.bin/tsx packages/persistence/prisma/seed-business-data.ts
116
+ depends_on:
117
+ postgresql-bootstrap:
118
+ condition: service_completed_successfully
119
+ smartgo-object-store-init:
120
+ condition: service_completed_successfully
121
+
122
+ smartgo-api:
123
+ <<: *smartgo-runtime
124
+ environment:
125
+ <<: *smartgo-component-env
126
+ HOST: 0.0.0.0
127
+ PORT: "3200"
128
+ ARTIFACT_DELIVERY_PROVIDER: s3
129
+ ARTIFACT_DELIVERY_S3_PUBLIC_ENDPOINT: http://${IDP_HTTP_BIND}:${IDP_HTTP_PORT}
130
+ ARTIFACT_DELIVERY_S3_BUCKET: smartgo-artifacts
131
+ ARTIFACT_DELIVERY_S3_REGION: us-east-1
132
+ ARTIFACT_DELIVERY_MAX_TTL_SECONDS: "900"
133
+ command: [node, services/smartgo-api/dist/index.js]
134
+ expose:
135
+ - "3200"
136
+ healthcheck:
137
+ test: [CMD, node, -e, "fetch('http://127.0.0.1:3200/ready').then(r=>{if(!r.ok)process.exit(1)}).catch(()=>process.exit(1))"]
138
+ <<: *smartgo-health
139
+ depends_on:
140
+ smartgo-migrate:
141
+ condition: service_completed_successfully
142
+
143
+ smartgo-agent-runtime:
144
+ <<: *smartgo-runtime
145
+ environment:
146
+ <<: *smartgo-component-env
147
+ HOST: 0.0.0.0
148
+ PORT: "3400"
149
+ SMARTGO_API_BASE_URL: http://smartgo-api:3200
150
+ AGENT_RUNTIME_FIXTURE_MODE: "true"
151
+ AGENT_RUNTIME_ALLOW_FIXTURE_AUTH: "true"
152
+ AGENT_RUNTIME_FIXTURE_TENANT_ID: tenant-bnu-primary
153
+ AGENT_RUNTIME_FIXTURE_SUBJECT: fixture:principal-zhu
154
+ command: [node, services/agent-runtime/dist/index.js]
155
+ expose:
156
+ - "3400"
157
+ healthcheck:
158
+ test: [CMD, node, -e, "fetch('http://127.0.0.1:3400/ready').then(r=>{if(!r.ok)process.exit(1)}).catch(()=>process.exit(1))"]
159
+ <<: *smartgo-health
160
+ depends_on:
161
+ smartgo-api:
162
+ condition: service_healthy
163
+
164
+ smartgo-worker:
165
+ <<: *smartgo-runtime
166
+ environment:
167
+ <<: *smartgo-component-env
168
+ HOST: 0.0.0.0
169
+ PORT: "3300"
170
+ WORKER_DELEGATE_BASE_URL: http://smartgo-api:3200
171
+ WORKER_TASK_TYPES: ARTIFACT_RENDER
172
+ WORKER_ARTIFACT_RENDERER: fixture
173
+ WORKER_ARTIFACT_FIXTURE_ENABLED: "true"
174
+ WORKER_ARTIFACT_OBJECT_STORE: s3
175
+ WORKER_ARTIFACT_S3_ENDPOINT: http://smartgo-object-store:9000
176
+ WORKER_ARTIFACT_S3_BUCKET: smartgo-artifacts
177
+ WORKER_ARTIFACT_S3_REGION: us-east-1
178
+ WORKER_ARTIFACT_RESULT_BASE_URL: http://smartgo-api:3200
179
+ command: [node, services/worker/dist/index.js]
180
+ expose:
181
+ - "3300"
182
+ healthcheck:
183
+ test: [CMD, node, -e, "fetch('http://127.0.0.1:3300/ready').then(r=>{if(!r.ok)process.exit(1)}).catch(()=>process.exit(1))"]
184
+ <<: *smartgo-health
185
+ depends_on:
186
+ smartgo-migrate:
187
+ condition: service_completed_successfully
188
+ smartgo-api:
189
+ condition: service_healthy
190
+
191
+ smartgo-gotology:
192
+ <<: *smartgo-runtime
193
+ tmpfs:
194
+ - /tmp:size=256m,mode=1777
195
+ - /workspace/apps/gotology/.artifacts/standalone/apps/gotology/.next/cache:size=128m,uid=${IDP_CONTAINER_UID},gid=${IDP_CONTAINER_GID},mode=0700
196
+ environment:
197
+ <<: *smartgo-component-env
198
+ HOSTNAME: 0.0.0.0
199
+ PORT: "3000"
200
+ SMARTGO_API_BASE_URL: http://smartgo-api:3200
201
+ SMARTGO_WORKER_API_BASE_URL: http://smartgo-worker:3300
202
+ SMARTGO_PUBLIC_URL: http://${IDP_HTTP_BIND}:${IDP_SMARTGO_GOTOLOGY_PORT}
203
+ PLATFORM_IDENTITY_ALLOW_INSECURE_LOCALHOST: "true"
204
+ command: [node, apps/gotology/.artifacts/standalone/server.js]
205
+ expose:
206
+ - "3000"
207
+ healthcheck:
208
+ test: [CMD, node, -e, "fetch('http://127.0.0.1:3000/api/health').then(r=>{if(!r.ok)process.exit(1)}).catch(()=>process.exit(1))"]
209
+ <<: *smartgo-health
210
+ depends_on:
211
+ smartgo-api:
212
+ condition: service_healthy
213
+ smartgo-worker:
214
+ condition: service_healthy
215
+
216
+ smartgo-operations:
217
+ <<: *smartgo-runtime
218
+ tmpfs:
219
+ - /tmp:size=256m,mode=1777
220
+ - /workspace/apps/operations/.artifacts/standalone/apps/operations/.next/cache:size=128m,uid=${IDP_CONTAINER_UID},gid=${IDP_CONTAINER_GID},mode=0700
221
+ environment:
222
+ <<: *smartgo-component-env
223
+ HOSTNAME: 0.0.0.0
224
+ PORT: "3101"
225
+ SMARTGO_API_BASE_URL: http://smartgo-api:3200
226
+ SMARTGO_PUBLIC_URL: http://${IDP_HTTP_BIND}:${IDP_SMARTGO_OPERATIONS_PORT}
227
+ PLATFORM_IDENTITY_ALLOW_INSECURE_LOCALHOST: "true"
228
+ command: [node, apps/operations/.artifacts/standalone/server.js]
229
+ expose:
230
+ - "3101"
231
+ healthcheck:
232
+ test: [CMD, node, -e, "fetch('http://127.0.0.1:3101/api/health').then(r=>{if(!r.ok)process.exit(1)}).catch(()=>process.exit(1))"]
233
+ <<: *smartgo-health
234
+ depends_on:
235
+ smartgo-api:
236
+ condition: service_healthy
237
+
238
+ smartgo-studio:
239
+ <<: *smartgo-runtime
240
+ tmpfs:
241
+ - /tmp:size=256m,mode=1777
242
+ - /workspace/apps/studio-poc/.artifacts/standalone/apps/studio-poc/.next/cache:size=256m,uid=${IDP_CONTAINER_UID},gid=${IDP_CONTAINER_GID},mode=0700
243
+ - /run/smartgo/studio:size=256m,uid=${IDP_CONTAINER_UID},gid=${IDP_CONTAINER_GID},mode=0700
244
+ environment:
245
+ <<: *smartgo-component-env
246
+ HOSTNAME: 0.0.0.0
247
+ PORT: "3002"
248
+ SMARTGO_API_BASE_URL: http://smartgo-api:3200
249
+ SMARTGO_WORKER_API_BASE_URL: http://smartgo-worker:3300
250
+ AGENT_RUNTIME_BASE_URL: http://smartgo-agent-runtime:3400
251
+ STUDIO_PUBLIC_URL: http://${IDP_HTTP_BIND}:${IDP_SMARTGO_STUDIO_PORT}
252
+ SMARTGO_STUDIO_STATE_MODE: ephemeral-fixture
253
+ SMARTGO_STUDIO_DATA_DIRECTORY: /run/smartgo/studio
254
+ PLATFORM_IDENTITY_ALLOW_INSECURE_LOCALHOST: "true"
255
+ command: [node, apps/studio-poc/.artifacts/standalone/server.js]
256
+ expose:
257
+ - "3002"
258
+ healthcheck:
259
+ test: [CMD, node, -e, "fetch('http://127.0.0.1:3002/api/health?ready=1').then(r=>{if(!r.ok)process.exit(1)}).catch(()=>process.exit(1))"]
260
+ <<: *smartgo-health
261
+ start_period: 60s
262
+ depends_on:
263
+ smartgo-api:
264
+ condition: service_healthy
265
+ smartgo-worker:
266
+ condition: service_healthy
267
+
268
+ networks:
269
+ idp_backend:
270
+ internal: true
271
+ idp_egress: {}
@@ -0,0 +1,64 @@
1
+ services:
2
+ tech:
3
+ image: ${IDP_TECH_IMAGE}
4
+ platform: ${IDP_RUNTIME_PLATFORM}
5
+ restart: unless-stopped
6
+ user: ${IDP_CONTAINER_UID}:${IDP_CONTAINER_GID}
7
+ environment:
8
+ IDP_COMPONENT_CONFIG_DIR: /run/idp-config
9
+ volumes:
10
+ - ${IDP_RENDER_DIR}/tech:/run/idp-config:ro
11
+ expose:
12
+ - "3698"
13
+ networks:
14
+ - idp_backend
15
+ - idp_egress
16
+ depends_on:
17
+ postgresql-bootstrap:
18
+ condition: service_completed_successfully
19
+ healthcheck:
20
+ test: [CMD, node, -e, "fetch('http://127.0.0.1:3698/ready').then(r=>{if(!r.ok)process.exit(1)}).catch(()=>process.exit(1))"]
21
+ interval: 15s
22
+ timeout: 5s
23
+ retries: 12
24
+ start_period: 45s
25
+ stop_grace_period: 30s
26
+ read_only: true
27
+ tmpfs:
28
+ - /tmp:size=256m,mode=1777
29
+ init: true
30
+ security_opt:
31
+ - no-new-privileges:true
32
+ cap_drop:
33
+ - ALL
34
+
35
+ tech-workbench:
36
+ image: ${IDP_TECH_WORKBENCH_IMAGE:-idp-tech-workbench:local}
37
+ platform: ${IDP_RUNTIME_PLATFORM}
38
+ restart: unless-stopped
39
+ expose:
40
+ - "3011"
41
+ networks:
42
+ - idp_backend
43
+ depends_on:
44
+ tech:
45
+ condition: service_healthy
46
+ healthcheck:
47
+ test: [CMD, node, -e, "fetch('http://127.0.0.1:3011/ready').then(r=>{if(!r.ok)process.exit(1)}).catch(()=>process.exit(1))"]
48
+ interval: 15s
49
+ timeout: 5s
50
+ retries: 8
51
+ start_period: 10s
52
+ read_only: true
53
+ tmpfs:
54
+ - /tmp:size=64m,mode=1777
55
+ init: true
56
+ security_opt:
57
+ - no-new-privileges:true
58
+ cap_drop:
59
+ - ALL
60
+
61
+ networks:
62
+ idp_backend:
63
+ internal: true
64
+ idp_egress: {}
@@ -0,0 +1,19 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://idp.internal/contracts/active-profile.v1.schema.json",
4
+ "title": "IDP Active Profile State v1",
5
+ "type": "object",
6
+ "additionalProperties": false,
7
+ "required": ["schemaVersion", "status", "profile", "services", "configDigest", "renderDigest", "updatedAt", "digest"],
8
+ "properties": {
9
+ "schemaVersion": { "const": 1 },
10
+ "status": { "enum": ["active", "stopped"] },
11
+ "profile": { "enum": ["tech-only", "foundation", "core", "portal", "flow", "registry", "full"] },
12
+ "services": { "type": "array", "minItems": 1, "uniqueItems": true, "items": { "enum": ["postgresql", "registry", "tech", "flow", "portal", "edge"] } },
13
+ "configDigest": { "$ref": "#/$defs/digest" },
14
+ "renderDigest": { "$ref": "#/$defs/digest" },
15
+ "updatedAt": { "type": "string", "format": "date-time" },
16
+ "digest": { "$ref": "#/$defs/digest" }
17
+ },
18
+ "$defs": { "digest": { "type": "string", "pattern": "^sha256:[0-9a-f]{64}$" } }
19
+ }
@@ -0,0 +1,49 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "urn:idp-deploy:asset-lifecycle:v1",
4
+ "title": "idp-deploy asset lifecycle v1",
5
+ "type": "object",
6
+ "additionalProperties": false,
7
+ "required": ["schemaVersion", "planId", "version", "approvedAt", "immutable", "archiveRoot", "activeComponents", "receipts", "policy", "digest"],
8
+ "properties": {
9
+ "schemaVersion": { "const": "idp-deploy.asset-lifecycle/v1" },
10
+ "planId": { "const": "idp-deploy.bench-deployment-ownership-reception@1" },
11
+ "version": { "const": 1 },
12
+ "approvedAt": { "type": "string", "format": "date" },
13
+ "immutable": { "const": true },
14
+ "archiveRoot": { "const": "archive" },
15
+ "activeComponents": { "type": "array", "uniqueItems": true, "items": { "enum": ["postgresql", "registry", "tech", "flow", "portal", "edge"] } },
16
+ "receipts": {
17
+ "type": "array",
18
+ "minItems": 1,
19
+ "items": {
20
+ "type": "object",
21
+ "additionalProperties": false,
22
+ "required": ["sourceProject", "sourceAsset", "sourceEvidence", "decision", "targetCapability", "targetPaths", "evidence", "remainingGates"],
23
+ "properties": {
24
+ "sourceProject": { "const": "bench" },
25
+ "sourceAsset": { "type": "string", "minLength": 1 },
26
+ "sourceEvidence": { "type": "string", "pattern": "^sha256:[0-9a-f]{64}$" },
27
+ "decision": { "enum": ["accepted", "replaced", "selectively-received", "deferred"] },
28
+ "targetCapability": { "type": "string", "minLength": 1 },
29
+ "targetPaths": { "type": "array", "uniqueItems": true, "items": { "type": "string", "minLength": 1 } },
30
+ "evidence": { "type": "array", "minItems": 1, "uniqueItems": true, "items": { "type": "string", "minLength": 1 } },
31
+ "remainingGates": { "type": "array", "uniqueItems": true, "items": { "type": "string", "minLength": 1 } }
32
+ }
33
+ }
34
+ },
35
+ "policy": {
36
+ "type": "object",
37
+ "additionalProperties": false,
38
+ "required": ["runtimeCrossRepositorySourceReads", "archiveIncludedInRuntime", "secretsOnlyFromExternalConfigDir", "unapprovedRemoteResources", "portalWriteProxy"],
39
+ "properties": {
40
+ "runtimeCrossRepositorySourceReads": { "const": false },
41
+ "archiveIncludedInRuntime": { "const": false },
42
+ "secretsOnlyFromExternalConfigDir": { "const": true },
43
+ "unapprovedRemoteResources": { "const": false },
44
+ "portalWriteProxy": { "const": false }
45
+ }
46
+ },
47
+ "digest": { "type": "string", "pattern": "^sha256:[0-9a-f]{64}$" }
48
+ }
49
+ }
@@ -0,0 +1,60 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://idp.internal/contracts/backup-generation.v1.schema.json",
4
+ "title": "IDP Backup Generation v1",
5
+ "type": "object",
6
+ "additionalProperties": false,
7
+ "required": ["schemaVersion", "generationId", "profile", "configDigest", "renderDigest", "expectedDatasets", "techBoundary", "files", "createdAt", "manifestDigest"],
8
+ "properties": {
9
+ "schemaVersion": { "const": 1 },
10
+ "generationId": { "type": "string", "pattern": "^[0-9TZ-]+-[0-9a-f]{12}$" },
11
+ "profile": { "enum": ["tech-only", "foundation", "core", "portal", "flow", "registry", "full"] },
12
+ "configDigest": { "$ref": "#/$defs/digest" },
13
+ "renderDigest": { "$ref": "#/$defs/digest" },
14
+ "manifestDigest": { "$ref": "#/$defs/digest" },
15
+ "createdAt": { "type": "string", "format": "date-time" },
16
+ "expectedDatasets": {
17
+ "type": "array",
18
+ "minItems": 1,
19
+ "uniqueItems": true,
20
+ "items": { "enum": ["postgresql:tech", "postgresql:backstage", "registry:packages"] }
21
+ },
22
+ "techBoundary": {
23
+ "oneOf": [
24
+ { "type": "null" },
25
+ {
26
+ "type": "object",
27
+ "additionalProperties": false,
28
+ "required": ["contract", "file", "size", "fileDigest", "factsDigest"],
29
+ "properties": {
30
+ "contract": { "const": "tech.backup-boundary.v1" },
31
+ "file": { "const": "tech-backup-boundary.json" },
32
+ "size": { "type": "integer", "minimum": 1 },
33
+ "fileDigest": { "$ref": "#/$defs/digest" },
34
+ "factsDigest": { "$ref": "#/$defs/digest" }
35
+ }
36
+ }
37
+ ]
38
+ },
39
+ "files": {
40
+ "type": "array",
41
+ "minItems": 1,
42
+ "items": {
43
+ "type": "object",
44
+ "additionalProperties": false,
45
+ "required": ["dataset", "kind", "file", "size", "digest"],
46
+ "properties": {
47
+ "dataset": { "enum": ["postgresql:tech", "postgresql:backstage", "registry:packages"] },
48
+ "kind": { "enum": ["postgresql", "registry"] },
49
+ "database": { "enum": ["tech", "backstage"] },
50
+ "file": { "type": "string", "pattern": "^[^/]+$" },
51
+ "size": { "type": "integer", "minimum": 1 },
52
+ "digest": { "$ref": "#/$defs/digest" }
53
+ }
54
+ }
55
+ }
56
+ },
57
+ "$defs": {
58
+ "digest": { "type": "string", "pattern": "^sha256:[0-9a-f]{64}$" }
59
+ }
60
+ }
@@ -0,0 +1,32 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://idp.internal/contracts/component-runtime.v1.schema.json",
4
+ "title": "IDP Component Runtime Projection v1",
5
+ "type": "object",
6
+ "additionalProperties": false,
7
+ "required": ["schemaVersion", "profile", "configDigest", "generatedAt", "files", "digest"],
8
+ "properties": {
9
+ "schemaVersion": { "const": 1 },
10
+ "profile": { "enum": ["tech-only", "foundation", "core", "portal", "flow", "registry", "full"] },
11
+ "configDigest": { "$ref": "#/$defs/digest" },
12
+ "generatedAt": { "type": "string", "format": "date-time" },
13
+ "files": {
14
+ "type": "array",
15
+ "items": {
16
+ "type": "object",
17
+ "additionalProperties": false,
18
+ "required": ["path", "mode", "size", "digest"],
19
+ "properties": {
20
+ "path": { "type": "string", "minLength": 1 },
21
+ "mode": { "enum": [256, 292] },
22
+ "size": { "type": "integer", "minimum": 0 },
23
+ "digest": { "$ref": "#/$defs/digest" }
24
+ }
25
+ }
26
+ },
27
+ "digest": { "$ref": "#/$defs/digest" }
28
+ },
29
+ "$defs": {
30
+ "digest": { "type": "string", "pattern": "^sha256:[0-9a-f]{64}$" }
31
+ }
32
+ }
@@ -0,0 +1,33 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://idp.internal/contracts/config-release.v1.schema.json",
4
+ "title": "IDP Config Release v1",
5
+ "type": "object",
6
+ "additionalProperties": false,
7
+ "required": ["schemaVersion", "application", "environmentRef", "reloadMode", "source", "files", "secretBindingDigests", "createdAt", "digest"],
8
+ "properties": {
9
+ "schemaVersion": { "const": "idp.config-release/v1" },
10
+ "application": { "$ref": "#/$defs/name" },
11
+ "environmentRef": { "$ref": "#/$defs/environmentRef" },
12
+ "reloadMode": { "enum": ["restart", "watch", "dynamic-provider"] },
13
+ "source": {
14
+ "type": "object", "additionalProperties": false, "required": ["kind", "ref", "digest"],
15
+ "properties": { "kind": { "enum": ["git", "oci", "config-provider"] }, "ref": { "type": "string", "minLength": 1 }, "digest": { "$ref": "#/$defs/digest" } }
16
+ },
17
+ "files": {
18
+ "type": "array",
19
+ "items": {
20
+ "type": "object", "additionalProperties": false, "required": ["path", "digest", "sensitive"],
21
+ "properties": { "path": { "type": "string", "minLength": 1 }, "digest": { "$ref": "#/$defs/digest" }, "sensitive": { "const": false } }
22
+ }
23
+ },
24
+ "secretBindingDigests": { "type": "array", "uniqueItems": true, "items": { "$ref": "#/$defs/digest" } },
25
+ "createdAt": { "type": "string", "format": "date-time" },
26
+ "digest": { "$ref": "#/$defs/digest" }
27
+ },
28
+ "$defs": {
29
+ "digest": { "type": "string", "pattern": "^sha256:[0-9a-f]{64}$" },
30
+ "name": { "type": "string", "pattern": "^[a-z][a-z0-9-]{1,62}$" },
31
+ "environmentRef": { "type": "string", "pattern": "^environment:[a-z][a-z0-9-]*(?:\\.[a-z0-9-]+)*@v[1-9][0-9]*$" }
32
+ }
33
+ }