@starci/hfs 4.7.21 → 4.7.22

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/CHANGELOG.md CHANGED
@@ -1,5 +1,8 @@
1
1
  # Changelog
2
2
 
3
+ ## 4.7.22 - 2026-10-22
4
+ - Fixed: the bundled runtime carries `modules/schemas/provision-operation.schema.yaml`; 4.7.21 left it out, so `starci app check` and `starci app lint` failed with ENOENT in every app whose stack declaration has an `operations` block. The composition reads both schemas through `new URL(..., import.meta.url)`, the form the runtime copy follows. Spec: `src/provision-operation-schema-bundle.spec.mjs`.
5
+
3
6
  ## 4.7.21 - 2026-10-22
4
7
  - Fixed: the release gate's Sonar read retries a network error or HTTP 5xx up to 5 times with backoff inside its 600 s wait; a 4xx and every gate status keep their verdict. Spec: `src/sonar-quality-gate.spec.mjs`.
5
8
  - Fixed: `starci app db dump` archives its parts with tar run inside the scratch directory and relative names only (no `-C`, no absolute path): GNU tar, first on PATH under Git Bash on Windows, read the absolute drive-letter archive path as a remote host and every backup failed with `DB_BACKUP_TOOL_FAILED`. Spec: `src/db-dump-archive.spec.mjs`.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@starci/hfs",
3
- "version": "4.7.21",
3
+ "version": "4.7.22",
4
4
  "description": "The StarCi app command implementation for scaffolding, linting, checking and synchronizing one product repository.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -76,14 +76,14 @@ pins:
76
76
  source: packages/test-world/package.json
77
77
  why: 'the shared e2e library of every back end (R47, R48), a devDependency of every back end: the warm stack behind toxiproxy, the network-edge fakes, the Nest boot, the typed useTestWorld handle, useSandbox for contract specs and the outage lock. Kafka is real own infra (the one digest-pinned apache/kafka KRaft image, a broker listener and proxy per slot, slot-prefixed topics, consumer groups and client ids) and Postgres is schema-per-context (a schema and a login role per context in a shared database). Each worker has its own data slot (<ns>_w<k>) with its own databases, Keycloak realm, leased Redis DB, bucket/collection/topic prefixes, fakes host, toxiproxy proxies and outage lock; a run provisions min(jest workers, workers cap, default 2) slots, and state file protocol 2 pairs exactly with @starci/jest-preset (TEST_WORLD_PAIR_MISMATCH otherwise). A modules world boots real peer apps beside its modules, world.apps.<name>.during(fn) is the outage of a peer app, w.keycloak.clientSecret(client) answers the run-generated secret of a confidential realm client, world.keycloak.events/sessions read the realm user events and live sessions, world.infra.postgresql.connection(name) takes one database connection down while the others serve, and world.resolve and scope.resolve take any Nest token. Every path a declaration names (`stack`, seeds, the realm, Dockerfiles) resolves from the app root (the directory of hfs.json); the globalSetup registers the path aliases as TypeScript resolves them. Its CLI main is exported at ./cli for starci app stack.'
78
78
  '@starci/cli':
79
- version: 1.7.21
79
+ version: 1.7.22
80
80
  group: starci
81
81
  install: registry
82
82
  side: both
83
83
  source: packages/cli/package.json
84
84
  why: 'the only StarCi command package; product repositories install it for starci app, while @starci/hfs remains its pinned transitive implementation.'
85
85
  '@starci/hfs':
86
- version: 4.7.21
86
+ version: 4.7.22
87
87
  group: starci
88
88
  install: registry
89
89
  side: both
@@ -0,0 +1,165 @@
1
+ $schema: https://json-schema.org/draft/2020-12/schema
2
+ $id: urn:starci:provision-operation:1
3
+ title: Target-bound provider operations
4
+ description: Public target and custody references for executable provider adapters; values never enter this declaration.
5
+ type: object
6
+ additionalProperties: false
7
+ required: [targets]
8
+ properties:
9
+ targets:
10
+ type: object
11
+ minProperties: 1
12
+ additionalProperties: {$ref: '#/$defs/target'}
13
+ $defs:
14
+ goalGrants:
15
+ type: object
16
+ additionalProperties: false
17
+ required: [schema, grants]
18
+ properties:
19
+ schema: {const: 'starci/provision-grants@1'}
20
+ grants:
21
+ type: array
22
+ items:
23
+ type: object
24
+ additionalProperties: false
25
+ required: [op, operation, digest]
26
+ properties:
27
+ op: {type: string, pattern: '^[a-z][a-z0-9-]*(\.[a-z][a-z0-9-]*)+$'}
28
+ operation: {type: string, pattern: '^[a-zA-Z0-9][a-zA-Z0-9-]{0,127}$'}
29
+ digest: {type: string, pattern: '^[a-f0-9]{64}$'}
30
+ credential:
31
+ oneOf:
32
+ - {$ref: '#/$defs/serviceCredential'}
33
+ - {$ref: '#/$defs/hostCredential'}
34
+ serviceCredential:
35
+ $ref: application-stacks.schema.yaml#/$defs/serviceCredential
36
+ hostCredential:
37
+ description: >-
38
+ A fixed host bridge for the admin role, never a value. sonar-selfhost-admin is the native self-hosted Sonar administrator;
39
+ sonar-runtime-secret-env is the variable `env` of the runtime's untracked secret.env (the reader `starci gate sonar up` uses),
40
+ for a SonarCloud target only.
41
+ oneOf:
42
+ - type: object
43
+ additionalProperties: false
44
+ required: [id, hostConnection]
45
+ properties:
46
+ id: {const: admin}
47
+ hostConnection: {const: sonar-selfhost-admin}
48
+ - type: object
49
+ additionalProperties: false
50
+ required: [id, hostConnection, env]
51
+ properties:
52
+ id: {const: admin}
53
+ hostConnection: {const: sonar-runtime-secret-env}
54
+ env: {type: string, pattern: '^[A-Z][A-Z0-9_]{0,63}$'}
55
+ purpose: {type: string, minLength: 1}
56
+ target:
57
+ type: object
58
+ additionalProperties: false
59
+ required: [provider, context, resource, credentials]
60
+ oneOf:
61
+ - required: [origin]
62
+ properties:
63
+ provider: {enum: [supabase-cloud, supabase-auth, sonar-server, sonar-community, sonar-cloud, app, github, ghcr]}
64
+ endpoint: false
65
+ - required: [endpoint]
66
+ properties:
67
+ provider: {const: app-stack}
68
+ origin: false
69
+ endpoint: {$ref: '#/$defs/swarmEndpoint'}
70
+ - required: [endpoint]
71
+ properties:
72
+ provider: {const: app-db}
73
+ origin: false
74
+ endpoint: {$ref: '#/$defs/databaseEndpoint'}
75
+ oneOf:
76
+ - properties:
77
+ context: {const: local}
78
+ endpoint:
79
+ properties:
80
+ mode: {const: local}
81
+ - properties:
82
+ endpoint:
83
+ properties:
84
+ mode: {enum: [linked, url-env]}
85
+ properties:
86
+ provider:
87
+ enum: [supabase-cloud, supabase-auth, sonar-server, sonar-community, sonar-cloud, app, github, ghcr, app-stack, app-db]
88
+ context:
89
+ enum: [local, development, staging, production]
90
+ origin:
91
+ type: string
92
+ pattern: '^https?://[^\s]+$'
93
+ description: Auth-free origin; the resolver permits HTTP only for an explicitly local loopback target.
94
+ endpoint:
95
+ type: object
96
+ description: Closed native endpoint selected by app-stack or app-db; public declaration checks precede custody and the effective private endpoint is compared before network access.
97
+ resource:
98
+ type: object
99
+ description: Adapter-owned public configuration; each adapter refuses fields outside its action contract.
100
+ credentials:
101
+ type: array
102
+ items: {$ref: '#/$defs/credential'}
103
+ description: Named roles using the existing service credential contract; ids become the execution role map.
104
+ optionalCredentials:
105
+ type: array
106
+ uniqueItems: true
107
+ items: {type: string, pattern: '^[a-z][a-z0-9-]*$'}
108
+ description: Declared roles whose absence may be inspected without substituting another credential.
109
+ destination:
110
+ $ref: '#/$defs/credential'
111
+ actions:
112
+ type: array
113
+ minItems: 1
114
+ uniqueItems: true
115
+ items: {type: string, pattern: '^[a-z][a-z0-9-]*(\.[a-z][a-z0-9-]*)+$'}
116
+ description: Exact action ids allowed for this target; the catalog and execution owner enforce the selected action.
117
+ swarmEndpoint:
118
+ type: object
119
+ additionalProperties: false
120
+ required: [kind, environment, stack, host, user, port]
121
+ properties:
122
+ kind: {const: docker-swarm}
123
+ environment: {type: string, pattern: '^[a-z][a-z0-9-]*$'}
124
+ stack: {type: string, pattern: '^[a-z][a-z0-9-]*$'}
125
+ host: {type: string, pattern: '^[a-zA-Z0-9][a-zA-Z0-9.-]*$'}
126
+ user: {type: string, pattern: '^[a-zA-Z0-9_][a-zA-Z0-9_.-]*$'}
127
+ port: {const: 22}
128
+ databaseEndpoint:
129
+ type: object
130
+ additionalProperties: false
131
+ required: [kind, mode, environment]
132
+ oneOf:
133
+ - required: [localProject, port]
134
+ properties:
135
+ mode: {const: local}
136
+ projectRef: false
137
+ urlEnv: false
138
+ host: false
139
+ database: false
140
+ user: false
141
+ - required: [projectRef]
142
+ properties:
143
+ mode: {const: linked}
144
+ localProject: false
145
+ port: false
146
+ urlEnv: false
147
+ host: false
148
+ database: false
149
+ user: false
150
+ - required: [urlEnv, host, port, database, user]
151
+ properties:
152
+ mode: {const: url-env}
153
+ localProject: false
154
+ projectRef: false
155
+ properties:
156
+ kind: {const: supabase-db}
157
+ mode: {enum: [local, linked, url-env]}
158
+ environment: {type: string, pattern: '^[a-z][a-z0-9-]*$'}
159
+ localProject: {type: string, pattern: '^[a-zA-Z0-9_][a-zA-Z0-9_.-]*$'}
160
+ projectRef: {type: string, pattern: '^[a-z0-9]{20}$'}
161
+ urlEnv: {type: string, pattern: '^[A-Z][A-Z0-9_]*$'}
162
+ host: {type: string, pattern: '^[a-zA-Z0-9][a-zA-Z0-9.-]*$'}
163
+ port: {type: integer, minimum: 1, maximum: 65535}
164
+ database: {type: string, pattern: '^[a-zA-Z0-9_][a-zA-Z0-9_.-]*$'}
165
+ user: {type: string, pattern: '^[a-zA-Z0-9_][a-zA-Z0-9_.-]*$'}
@@ -1,17 +1,17 @@
1
1
  // The schema of a stack declaration's `operations` block, composed once for its two readers: the provision target owner and the
2
2
  // stacks gate. provision-operation.schema.yaml refers to the service credential of application-stacks.schema.yaml; the composition
3
3
  // inlines that definition so the self-contained walker of json-schema.mjs resolves every reference.
4
+ // Both schemas are read through `new URL(<literal>, import.meta.url)`: that is the form sync-runtime follows, so the copy
5
+ // bundled in @starci/hfs carries them beside this module (a skillRoot join left provision-operation.schema.yaml out of it).
4
6
  import fs from 'node:fs';
5
- import path from 'node:path';
6
7
  import { parseYaml } from '../../engine/yaml.mjs';
7
- import { skillRoot } from '../../engine/runtime-root.mjs';
8
8
 
9
9
  /** The `$ref` application-stacks.schema.yaml uses for its `operations` block. */
10
10
  export const PROVISION_OPERATION_SCHEMA_REF = 'provision-operation.schema.yaml';
11
11
 
12
12
  /** The composed `operations` schema, read from this runtime's modules/schemas. */
13
13
  export function provisionOperationSchema() {
14
- const schema = parseYaml(fs.readFileSync(path.join(skillRoot, 'modules/schemas', PROVISION_OPERATION_SCHEMA_REF), 'utf8'));
15
- const stacks = parseYaml(fs.readFileSync(path.join(skillRoot, 'modules/schemas/application-stacks.schema.yaml'), 'utf8'));
14
+ const schema = parseYaml(fs.readFileSync(new URL('../../modules/schemas/provision-operation.schema.yaml', import.meta.url), 'utf8'));
15
+ const stacks = parseYaml(fs.readFileSync(new URL('../../modules/schemas/application-stacks.schema.yaml', import.meta.url), 'utf8'));
16
16
  return { ...schema, $defs: { ...schema.$defs, serviceCredential: stacks.$defs.serviceCredential } };
17
17
  }