@starci/hfs 4.4.1 → 4.5.1

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 (66) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/ci/cli.mjs +64 -0
  3. package/ci/github.mjs +41 -0
  4. package/ci/secret.mjs +28 -0
  5. package/ci/vars.mjs +33 -0
  6. package/ci/verify.mjs +36 -0
  7. package/db/backup-receipt.mjs +129 -0
  8. package/db/dump.mjs +66 -0
  9. package/db/migrate.mjs +4 -1
  10. package/db/reset.mjs +125 -0
  11. package/emit/db-types.mjs +98 -5
  12. package/lint/run.mjs +28 -6
  13. package/package.json +2 -1
  14. package/release/ci-red.mjs +70 -0
  15. package/release/gate.mjs +98 -27
  16. package/release/index.mjs +6 -4
  17. package/release/push.mjs +1 -1
  18. package/runtime/knowledge/hfs/canon-pins.yaml +5 -5
  19. package/runtime/knowledge/hfs/rules.yaml +95 -4
  20. package/runtime/modules/kernel/failure-codes.yaml +60 -0
  21. package/runtime/modules/schemas/application-stacks.schema.yaml +134 -1
  22. package/runtime/packages/cli/src/catalog.generated.mjs +243 -20
  23. package/runtime/scripts/hfs/ci-declaration.mjs +102 -0
  24. package/runtime/scripts/hfs/rules/a15-findings.mjs +9 -0
  25. package/runtime/scripts/hfs/rules/app-workflow-findings.mjs +10 -0
  26. package/runtime/scripts/hfs/rules/ci-custody.mjs +104 -0
  27. package/runtime/scripts/hfs/rules/deploy-workflow.mjs +6 -19
  28. package/runtime/scripts/hfs/rules/fe-build-args.mjs +142 -0
  29. package/runtime/scripts/hfs/rules/supply-chain.mjs +40 -3
  30. package/runtime/scripts/hfs/rules/workflow-contexts.mjs +103 -0
  31. package/runtime/scripts/lib/secret-patterns.mjs +2 -2
  32. package/src/main.mjs +17 -6
  33. package/stack/context.mjs +13 -1
  34. package/stack/docker-transport.mjs +93 -15
  35. package/stack/release-store.mjs +12 -7
  36. package/stack/remote.mjs +14 -6
  37. package/stack/ssh-session.mjs +178 -0
  38. package/sync/ci-commands.mjs +205 -1
  39. package/sync/index.mjs +42 -16
  40. package/sync/quality-services.mjs +61 -0
  41. package/sync/readme-badges.mjs +44 -0
  42. package/sync/stack-images.mjs +29 -3
  43. package/templates/app/ci-workflows/github/workflows/ci.yml +33 -25
  44. package/templates/app/ci-workflows/github/workflows/e2e.yml +1 -0
  45. package/templates/app/ci-workflows/github/workflows/images.yml +25 -2
  46. package/templates/app/ci-workflows/github/workflows/stack-deploy.yml +8 -2
  47. package/templates/app/ci-workflows/install-steps.yml +23 -0
  48. package/templates/app/ci-workflows/jest-cache.yml +8 -0
  49. package/templates/app/ci-workflows/lint-base.yml +16 -0
  50. package/templates/app/ci-workflows/sonar-steps.yml +3 -9
  51. package/templates/app/ci-workflows-lite/github/workflows/ci.yml +36 -36
  52. package/templates/app/ci-workflows-lite/github/workflows/db-deploy.yml +3 -1
  53. package/templates/app/ci-workflows-lite/github/workflows/images.yml +25 -2
  54. package/templates/app/ci-workflows-lite/github/workflows/stack-deploy.yml +8 -2
  55. package/templates/app/gitignore +2 -0
  56. package/templates/app/gitignore-lite +2 -0
  57. package/templates/app/quality-config/codecov.yml +6 -6
  58. package/templates/app/quality-config/sonar-project.properties +1 -0
  59. package/templates/app/readme-badges/README.md +1 -0
  60. package/templates/app/skeleton/.github/dependabot.yml +1 -14
  61. package/templates/app/skeleton/.starcistacks/application-stacks.yaml +62 -3
  62. package/templates/app/skeleton/README.md +6 -0
  63. package/templates/app/skeleton-lite/.github/dependabot.yml +1 -14
  64. package/templates/app/skeleton-lite/.starcistacks/application-stacks.yaml +58 -3
  65. package/templates/app/skeleton-lite/README.md +6 -0
  66. package/templates/app/upgrade-full/.starcistacks/application-stacks.yaml +53 -1
@@ -2,6 +2,8 @@
2
2
  # The source models declare intended compute; they prove no completed deployment.
3
3
  # All-zero application digests are illustrative and must be replaced by verified release digests.
4
4
  schema: starci/application-stacks@1
5
+ # To render README badges, declare ci.github: {repository: owner/repo, defaultBranch: main}.
6
+ # A GitHub package.json repository URL also enables the managed block.
5
7
  sources:
6
8
  - repository: {{project}}
7
9
  backing:
@@ -145,9 +147,12 @@ environments:
145
147
  app: api
146
148
  web:
147
149
  app: web
150
+ # Public browser configuration; replace these placeholders before deployment.
148
151
  buildArgs:
149
152
  values:
150
153
  NEXT_PUBLIC_SITE_URL: "https://{{project}}.example.invalid"
154
+ NEXT_PUBLIC_SUPABASE_URL: "https://supabase.{{project}}.example.invalid"
155
+ NEXT_PUBLIC_SUPABASE_ANON_KEY: "REPLACE_WITH_PUBLIC_SUPABASE_ANON_KEY"
151
156
  volumes:
152
157
  - {{project}}-production-ingress-data
153
158
  - {{project}}-production-ingress-config-data
@@ -175,19 +180,69 @@ environments:
175
180
  k8s:
176
181
  status: deferred
177
182
  reason: Lite production uses Docker Swarm with managed Supabase backing; Kubernetes belongs to a future full-edition deployment.
183
+ ci:
184
+ secrets:
185
+ - {name: SONAR_TOKEN, scope: repository, purpose: Sonar analysis token provisioned for this app, optional: true}
186
+ - {name: SOPS_AGE_KEY, scope: environment, environment: production, purpose: Decrypt app members during deployment, optional: true}
187
+ - {name: VPS_SSH_KEY, scope: environment, environment: production, purpose: Deployment SSH key, optional: true}
188
+ - {name: VPS_KNOWN_HOSTS, scope: environment, environment: production, purpose: Pinned deployment SSH host keys, optional: true}
189
+ vars:
190
+ - {name: SONAR_HOST_URL, scope: repository, value: "https://sonar.{{project}}.example.invalid", purpose: Documentation endpoint to replace with this app's public Sonar host, optional: true}
191
+ - {name: VPS_HOST, scope: environment, environment: production, value: 203.0.113.10, purpose: Documentation deployment address to replace before use, optional: true}
192
+ - {name: VPS_USER, scope: environment, environment: production, value: deploy, purpose: Documentation deployment user to replace before use, optional: true}
178
193
  services:
179
194
  sonar:
180
195
  provider: sonarqube
196
+ optional: true
181
197
  mode: local
182
198
  qualityGate: {{sonarGate}}
183
- host: {local: http://127.0.0.1:9000}
199
+ host: {local: http://127.0.0.1:9000, public: "https://sonar.{{project}}.example.invalid"}
184
200
  stack:
185
201
  owner: host
186
202
  root: .claude/ext/sonar
187
203
  environment: dev
188
204
  compose: compose.yaml
189
205
  auth: token
190
- ci: {wiring: optional-follow-up}
206
+ credentials: []
207
+ projects: [{repository: "{{project}}", key: "{{project}}"}]
208
+ ci: {wiring: optional-follow-up, workflow: .github/workflows/ci.yml, token: SONAR_TOKEN, hostVar: SONAR_HOST_URL}
191
209
  ownerAction:
192
- needed: Provision the shared host Sonar project and its analysis credential through sealed custody.
210
+ needed: Provision this app's Sonar host and project, then set SONAR_TOKEN with starci app ci secret set and sync SONAR_HOST_URL.
193
211
  reason: A fresh app declares its quality service without fabricating credentials or a successful analysis.
212
+ codecov:
213
+ provider: codecov
214
+ mode: hosted
215
+ purpose: Report application coverage through GitHub OIDC.
216
+ auth: oidc
217
+ target: 100
218
+ components: auto
219
+ required: true
220
+ ci: {wiring: optional-follow-up, workflow: .github/workflows/ci.yml}
221
+ ownerAction: none
222
+ dependabot:
223
+ provider: github
224
+ mode: hosted
225
+ purpose: Keep application dependencies and workflow actions current.
226
+ ecosystems: [npm, docker, github-actions]
227
+ schedule: {interval: weekly}
228
+ groups: {minorPatch: grouped, major: per-package}
229
+ ignore: ['@starci/*']
230
+ security: immediate
231
+ ownerAction: none
232
+ audit:
233
+ provider: npm
234
+ mode: local
235
+ purpose: Refuse high severity production dependency vulnerabilities.
236
+ level: high
237
+ omitDev: true
238
+ in: [release-gate, ci]
239
+ ownerAction: none
240
+ container-registry:
241
+ provider: ghcr
242
+ mode: hosted
243
+ purpose: Publish this app's deployment images with the workflow GitHub token.
244
+ host: {public: https://ghcr.io}
245
+ auth: github-token
246
+ projects: [{repository: "{{project}}", key: "{{project}}"}]
247
+ ci: {wiring: optional-follow-up}
248
+ ownerAction: none
@@ -18,6 +18,10 @@ TypeScript everywhere, NestJS in `be/`, Next.js with next-intl in `fe/`, Supabas
18
18
  - `.starcistacks/`: value-free environment metadata and encrypted-secret custody.
19
19
  - `.starciwork/`: `.gitignore`, `.starciwork/workspace.yaml` project metadata and repo roles, and optional brand drawing records, references, and assets.
20
20
 
21
+ ## Status badges
22
+
23
+ Declare `ci.github.repository` and `ci.github.defaultBranch` in `.starcistacks/application-stacks.yaml` (or set the GitHub `repository` URL in `package.json`), then run `npx starci app sync --write`. Sync inserts a managed badge block after the title; `npx starci app sync --check` verifies it.
24
+
21
25
  ## Development
22
26
 
23
27
  ```sh
@@ -32,6 +36,8 @@ npm run build:fe
32
36
 
33
37
  The API reads `PORT`, `HTTP_SECURITY_ALLOWED_ORIGINS`, `PRIMARY_DB_URL`, `PRIMARY_DB_SCHEMA`, `SUPABASE_URL`, and `SUPABASE_SERVICE_ROLE_KEY`. The web app reads `NEXT_PUBLIC_SITE_URL`, `NEXT_PUBLIC_SUPABASE_URL`, `NEXT_PUBLIC_SUPABASE_ANON_KEY`, and, once the first GraphQL operation exists, `NEXT_PUBLIC_GRAPHQL_URL`. Missing configuration stops the relevant process with a named error; no template supplies credential defaults.
34
38
 
39
+ Production browser build values live in `.starcistacks/application-stacks.yaml` under `environments.production.deploy.images.web.buildArgs.values`. Before building deployment images, replace the placeholders with your site's public origin, your Supabase project's public URL, and its public anonymous key. These values reach every browser; keep the service role key in sealed runtime custody.
40
+
35
41
  `npm test` runs the back end's unit specs with per-file coverage. Optional integration specs run with `npm run test:integration` against the local Supabase stack (`npm run db:start`); a lite app has no e2e world.
36
42
 
37
43
  The public runtime template tracks only sealed member names. Scaffolding creates this app's own age recipient and encrypts generated placeholder values into the declared `.starcistacks/<environment>/secrets/*.enc` members. Keep the matching host age identity in untracked local custody, then use `starci app secret set` to replace each placeholder with an actual value before deployment. Product apps retain sealed member custody. Runtime specs use disposable copies with ephemeral identities and remove them afterwards.
@@ -1,4 +1,6 @@
1
1
  schema: starci/application-stacks@1
2
+ # To render README badges, declare ci.github: {repository: owner/repo, defaultBranch: main}.
3
+ # A GitHub package.json repository URL also enables the managed block.
2
4
  sources:
3
5
  - repository: "{{project}}"
4
6
  components:
@@ -28,11 +30,61 @@ environments:
28
30
  k8s:
29
31
  status: deferred
30
32
  reason: The upgrade establishes the full local stack first; deployment topology is selected separately.
33
+ ci:
34
+ secrets:
35
+ - {name: SONAR_TOKEN, scope: repository, purpose: Sonar analysis token provisioned for this app, optional: true}
36
+ - {name: SOPS_AGE_KEY, scope: repository, purpose: Decrypt app members during deployment, optional: true}
37
+ - {name: VPS_SSH_KEY, scope: repository, purpose: Deployment SSH key, optional: true}
38
+ - {name: VPS_KNOWN_HOSTS, scope: repository, purpose: Pinned deployment SSH host keys, optional: true}
39
+ vars:
40
+ - {name: SONAR_HOST_URL, scope: repository, value: "https://sonar.{{project}}.example.invalid", purpose: Documentation endpoint to replace with this app's public Sonar host, optional: true}
41
+ - {name: VPS_HOST, scope: repository, value: 203.0.113.10, purpose: Documentation deployment address to replace before use, optional: true}
42
+ - {name: VPS_USER, scope: repository, value: deploy, purpose: Documentation deployment user to replace before use, optional: true}
31
43
  services:
32
44
  sonar:
33
45
  provider: sonarqube
46
+ optional: true
34
47
  mode: disabled
35
48
  reason: Enable the repository's Sonar service when a host and project token are provisioned.
36
49
  qualityGate: starci-quality
37
- ci: { wiring: not-used }
50
+ credentials: []
51
+ projects: [{repository: "{{project}}", key: "{{project}}"}]
52
+ ci: {wiring: optional-follow-up, workflow: .github/workflows/ci.yml, token: SONAR_TOKEN, hostVar: SONAR_HOST_URL}
53
+ ownerAction: none
54
+ codecov:
55
+ provider: codecov
56
+ mode: hosted
57
+ purpose: Report application coverage through GitHub OIDC.
58
+ auth: oidc
59
+ target: 100
60
+ components: auto
61
+ required: true
62
+ ci: {wiring: optional-follow-up, workflow: .github/workflows/ci.yml}
63
+ ownerAction: none
64
+ dependabot:
65
+ provider: github
66
+ mode: hosted
67
+ purpose: Keep application dependencies and workflow actions current.
68
+ ecosystems: [npm, docker, github-actions]
69
+ schedule: {interval: weekly}
70
+ groups: {minorPatch: grouped, major: per-package}
71
+ ignore: ['@starci/*']
72
+ security: immediate
73
+ ownerAction: none
74
+ audit:
75
+ provider: npm
76
+ mode: local
77
+ purpose: Refuse high severity production dependency vulnerabilities.
78
+ level: high
79
+ omitDev: true
80
+ in: [release-gate, ci]
81
+ ownerAction: none
82
+ container-registry:
83
+ provider: ghcr
84
+ mode: hosted
85
+ purpose: Publish this app's deployment images with the workflow GitHub token.
86
+ host: {public: https://ghcr.io}
87
+ auth: github-token
88
+ projects: [{repository: "{{project}}", key: "{{project}}"}]
89
+ ci: {wiring: optional-follow-up}
38
90
  ownerAction: none