prizmkit 1.1.153 → 1.1.155
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/bundled/VERSION.json +3 -3
- package/bundled/adapters/codex/skill-adapter.js +1 -1
- package/bundled/adapters/pi/skill-adapter.js +2 -1
- package/bundled/dev-pipeline/.env.example +2 -6
- package/bundled/dev-pipeline/README.md +120 -113
- package/bundled/dev-pipeline/assets/skill-subagent-integration.md +1 -1
- package/bundled/dev-pipeline/prizmkit_runtime/checkpoint_state.py +355 -15
- package/bundled/dev-pipeline/prizmkit_runtime/cli.py +189 -110
- package/bundled/dev-pipeline/prizmkit_runtime/commands.py +146 -111
- package/bundled/dev-pipeline/prizmkit_runtime/daemon.py +4 -20
- package/bundled/dev-pipeline/prizmkit_runtime/gitops.py +48 -14
- package/bundled/dev-pipeline/prizmkit_runtime/interoperability.py +0 -1
- package/bundled/dev-pipeline/prizmkit_runtime/paths.py +0 -3
- package/bundled/dev-pipeline/prizmkit_runtime/reset.py +122 -15
- package/bundled/dev-pipeline/prizmkit_runtime/reset_preserve.py +1 -1
- package/bundled/dev-pipeline/prizmkit_runtime/runner_classification.py +50 -2
- package/bundled/dev-pipeline/prizmkit_runtime/runner_models.py +1 -10
- package/bundled/dev-pipeline/prizmkit_runtime/runner_prompts.py +3 -3
- package/bundled/dev-pipeline/prizmkit_runtime/runners.py +139 -74
- package/bundled/dev-pipeline/prizmkit_runtime/runtime_commit.py +482 -0
- package/bundled/dev-pipeline/prizmkit_runtime/status.py +106 -1
- package/bundled/dev-pipeline/prizmkit_runtime/test_result.py +64 -11
- package/bundled/dev-pipeline/scripts/generate-bootstrap-prompt.py +145 -367
- package/bundled/dev-pipeline/scripts/generate-bugfix-prompt.py +91 -62
- package/bundled/dev-pipeline/scripts/generate-refactor-prompt.py +105 -69
- package/bundled/dev-pipeline/scripts/init-bugfix-pipeline.py +2 -2
- package/bundled/dev-pipeline/scripts/prompt_framework.py +36 -41
- package/bundled/dev-pipeline/scripts/update-bug-status.py +197 -71
- package/bundled/dev-pipeline/scripts/update-checkpoint.py +77 -16
- package/bundled/dev-pipeline/scripts/update-feature-status.py +46 -121
- package/bundled/dev-pipeline/scripts/update-refactor-status.py +46 -123
- package/bundled/dev-pipeline/scripts/utils.py +119 -0
- package/bundled/dev-pipeline/templates/bootstrap-prompt.md +22 -27
- package/bundled/dev-pipeline/templates/bootstrap-tier3.md +71 -104
- package/bundled/dev-pipeline/templates/bug-fix-list-schema.json +3 -2
- package/bundled/dev-pipeline/templates/bugfix-bootstrap-prompt.md +59 -111
- package/bundled/dev-pipeline/templates/refactor-bootstrap-prompt.md +37 -72
- package/bundled/dev-pipeline/templates/sections/artifact-manifest.md +39 -0
- package/bundled/dev-pipeline/templates/sections/bugfix-critical-paths.md +3 -1
- package/bundled/dev-pipeline/templates/sections/bugfix-phase-commit-report.md +8 -25
- package/bundled/dev-pipeline/templates/sections/bugfix-phase-diagnose-plan.md +3 -3
- package/bundled/dev-pipeline/templates/sections/bugfix-phase-implement.md +2 -2
- package/bundled/dev-pipeline/templates/sections/bugfix-phase-review.md +3 -3
- package/bundled/dev-pipeline/templates/sections/bugfix-phase-test.md +2 -2
- package/bundled/dev-pipeline/templates/sections/bugfix-reminders.md +4 -4
- package/bundled/dev-pipeline/templates/sections/bugfix-session-context.md +0 -1
- package/bundled/dev-pipeline/templates/sections/checkpoint-system.md +7 -4
- package/bundled/dev-pipeline/templates/sections/context-budget-rules.md +14 -27
- package/bundled/dev-pipeline/templates/sections/feature-completion-summary.md +20 -0
- package/bundled/dev-pipeline/templates/sections/phase-commit-full.md +8 -71
- package/bundled/dev-pipeline/templates/sections/phase-implement-full.md +7 -7
- package/bundled/dev-pipeline/templates/sections/phase-prizmkit-test.md +3 -3
- package/bundled/dev-pipeline/templates/sections/phase-review-full.md +4 -4
- package/bundled/dev-pipeline/templates/sections/phase-specify-plan-full.md +5 -17
- package/bundled/dev-pipeline/templates/sections/refactor-critical-paths.md +3 -1
- package/bundled/dev-pipeline/templates/sections/refactor-phase-commit-report.md +10 -23
- package/bundled/dev-pipeline/templates/sections/refactor-phase-implement.md +2 -2
- package/bundled/dev-pipeline/templates/sections/refactor-phase-plan.md +2 -2
- package/bundled/dev-pipeline/templates/sections/refactor-phase-review.md +3 -3
- package/bundled/dev-pipeline/templates/sections/refactor-phase-test.md +2 -2
- package/bundled/dev-pipeline/templates/sections/refactor-reminders.md +7 -7
- package/bundled/dev-pipeline/templates/sections/refactor-session-context.md +0 -1
- package/bundled/dev-pipeline/templates/sections/retrospective.md +12 -0
- package/bundled/dev-pipeline/templates/sections/runtime-commit-handoff.md +35 -0
- package/bundled/dev-pipeline/templates/session-status-schema.json +45 -62
- package/bundled/dev-pipeline/tests/test_auto_skip.py +111 -32
- package/bundled/dev-pipeline/tests/test_checkpoint_state.py +617 -30
- package/bundled/dev-pipeline/tests/test_generate_bootstrap_prompt.py +262 -194
- package/bundled/dev-pipeline/tests/test_generate_bugfix_prompt.py +62 -23
- package/bundled/dev-pipeline/tests/test_generate_refactor_prompt.py +76 -28
- package/bundled/dev-pipeline/tests/test_python_runner_parity.py +281 -206
- package/bundled/dev-pipeline/tests/test_recovery_workflow.py +322 -0
- package/bundled/dev-pipeline/tests/test_reset_modes.py +935 -0
- package/bundled/dev-pipeline/tests/test_reset_preserve.py +5 -7
- package/bundled/dev-pipeline/tests/test_runtime_commit.py +608 -0
- package/bundled/dev-pipeline/tests/test_unified_cli.py +617 -188
- package/bundled/skills/_metadata.json +9 -9
- package/bundled/skills/app-planner/SKILL.md +3 -3
- package/bundled/skills/app-planner/references/generated-plan-review.md +2 -1
- package/bundled/skills/app-planner/references/rules/backend/derivation-rules.md +56 -64
- package/bundled/skills/app-planner/references/rules/backend/fixed-rules.md +85 -240
- package/bundled/skills/app-planner/references/rules/backend/question-bank.md +25 -25
- package/bundled/skills/app-planner/references/rules/backend/question-manifest.json +16 -7
- package/bundled/skills/app-planner/references/rules/backend/template.md +74 -92
- package/bundled/skills/app-planner/references/rules/database/derivation-rules.md +93 -93
- package/bundled/skills/app-planner/references/rules/database/fixed-rules.md +66 -173
- package/bundled/skills/app-planner/references/rules/database/question-bank.md +31 -26
- package/bundled/skills/app-planner/references/rules/database/question-manifest.json +13 -4
- package/bundled/skills/app-planner/references/rules/database/template.md +76 -98
- package/bundled/skills/app-planner/references/rules/frontend/derivation-rules.md +68 -95
- package/bundled/skills/app-planner/references/rules/frontend/fixed-rules.md +93 -166
- package/bundled/skills/app-planner/references/rules/frontend/question-bank.md +46 -36
- package/bundled/skills/app-planner/references/rules/frontend/question-manifest.json +11 -2
- package/bundled/skills/app-planner/references/rules/frontend/template.md +79 -257
- package/bundled/skills/app-planner/references/rules/mobile/derivation-rules.md +91 -99
- package/bundled/skills/app-planner/references/rules/mobile/fixed-rules.md +73 -246
- package/bundled/skills/app-planner/references/rules/mobile/question-bank.md +17 -17
- package/bundled/skills/app-planner/references/rules/mobile/question-manifest.json +17 -2
- package/bundled/skills/app-planner/references/rules/mobile/template.md +73 -85
- package/bundled/skills/app-planner/references/rules-configuration.md +133 -65
- package/bundled/skills/app-planner/scripts/validate-rules-configuration.py +291 -0
- package/bundled/skills/bug-planner/references/schema-validation.md +1 -1
- package/bundled/skills/bug-planner/scripts/validate-bug-list.py +1 -1
- package/bundled/skills/bugfix-pipeline-launcher/SKILL.md +21 -13
- package/bundled/skills/feature-pipeline-launcher/SKILL.md +22 -14
- package/bundled/skills/prizmkit/SKILL.md +17 -18
- package/bundled/skills/prizmkit/references/workflow-state-protocol.md +22 -18
- package/bundled/skills/prizmkit-code-review/SKILL.md +22 -58
- package/bundled/skills/prizmkit-code-review/references/independent-code-review.md +6 -6
- package/bundled/skills/prizmkit-code-review/references/review-report-template.md +2 -2
- package/bundled/skills/prizmkit-committer/SKILL.md +82 -132
- package/bundled/skills/prizmkit-deploy/SKILL.md +27 -11
- package/bundled/skills/prizmkit-deploy/assets/deploy-document-template.md +89 -0
- package/bundled/skills/prizmkit-deploy/references/ci-cd-workflows.md +44 -14
- package/bundled/skills/prizmkit-deploy/references/cloud-platform-deploy.md +19 -3
- package/bundled/skills/prizmkit-deploy/references/database-setup.md +22 -12
- package/bundled/skills/prizmkit-deploy/references/deploy-config-schema.md +3 -1
- package/bundled/skills/prizmkit-deploy/references/deploy-history-schema.md +22 -6
- package/bundled/skills/prizmkit-deploy/references/deploy-metadata-schema.json +49 -0
- package/bundled/skills/prizmkit-deploy/references/live-validation-notes.md +1 -1
- package/bundled/skills/prizmkit-deploy/references/pending-input-schema.json +164 -0
- package/bundled/skills/prizmkit-deploy/references/ssh-adapter-flow.md +9 -8
- package/bundled/skills/prizmkit-deploy/references/ssh-execution-flow.md +6 -6
- package/bundled/skills/prizmkit-implement/SKILL.md +30 -66
- package/bundled/skills/prizmkit-implement/references/implementation-subagent-procedure.md +4 -4
- package/bundled/skills/prizmkit-init/SKILL.md +4 -0
- package/bundled/skills/prizmkit-plan/SKILL.md +21 -64
- package/bundled/skills/prizmkit-plan/references/artifact-identity.md +38 -0
- package/bundled/skills/prizmkit-plan/references/independent-plan-review.md +4 -4
- package/bundled/skills/prizmkit-plan/references/review-plan-spec-loop.md +5 -5
- package/bundled/skills/prizmkit-prizm-docs/SKILL.md +11 -1
- package/bundled/skills/prizmkit-retrospective/SKILL.md +63 -77
- package/bundled/skills/prizmkit-retrospective/references/knowledge-injection-steps.md +3 -3
- package/bundled/skills/prizmkit-retrospective/references/retrospective-result-schema.json +138 -0
- package/bundled/skills/prizmkit-retrospective/references/structural-sync-steps.md +17 -23
- package/bundled/skills/prizmkit-test/SKILL.md +64 -51
- package/bundled/skills/prizmkit-test/references/boundary-contract-and-test-double-guidance.md +206 -0
- package/bundled/skills/prizmkit-test/references/independent-test-review.md +17 -9
- package/bundled/skills/prizmkit-test/references/test-coverage-model.md +45 -21
- package/bundled/skills/prizmkit-test/references/test-report-template.md +20 -13
- package/bundled/skills/prizmkit-workflow/SKILL.md +35 -37
- package/bundled/skills/prizmkit-workflow/references/artifact-identity.md +34 -0
- package/bundled/skills/prizmkit-workflow/references/workflow-state-protocol.md +22 -18
- package/bundled/skills/recovery-workflow/SKILL.md +9 -6
- package/bundled/skills/recovery-workflow/evals/evals.json +2 -2
- package/bundled/skills/recovery-workflow/references/detection.md +7 -6
- package/bundled/skills/recovery-workflow/scripts/detect-recovery-state.py +16 -6
- package/bundled/skills/refactor-pipeline-launcher/SKILL.md +21 -13
- package/bundled/templates/project-memory-template.md +19 -11
- package/package.json +1 -1
- package/src/scaffold.js +33 -22
- package/bundled/dev-pipeline/prizmkit_runtime/runner_recovery.py +0 -228
- package/bundled/dev-pipeline/scripts/generate-recovery-prompt.py +0 -767
- package/bundled/dev-pipeline/templates/sections/bugfix-artifacts.md +0 -16
- package/bundled/dev-pipeline/templates/sections/bugfix-session-status.md +0 -31
- package/bundled/dev-pipeline/templates/sections/critical-paths-agent.md +0 -7
- package/bundled/dev-pipeline/templates/sections/critical-paths-lite.md +0 -7
- package/bundled/dev-pipeline/templates/sections/directory-convention-agent.md +0 -9
- package/bundled/dev-pipeline/templates/sections/directory-convention-lite.md +0 -6
- package/bundled/dev-pipeline/templates/sections/headless-commit-authorization.md +0 -15
- package/bundled/dev-pipeline/templates/sections/phase-commit.md +0 -61
- package/bundled/dev-pipeline/templates/sections/phase-context-snapshot-agent-suffix.md +0 -24
- package/bundled/dev-pipeline/templates/sections/phase-context-snapshot-lite-suffix.md +0 -12
- package/bundled/dev-pipeline/templates/sections/phase-implement-agent.md +0 -44
- package/bundled/dev-pipeline/templates/sections/phase-implement-lite.md +0 -25
- package/bundled/dev-pipeline/templates/sections/phase-plan-agent.md +0 -20
- package/bundled/dev-pipeline/templates/sections/phase-plan-lite.md +0 -20
- package/bundled/dev-pipeline/templates/sections/phase-review-agent.md +0 -20
- package/bundled/dev-pipeline/templates/sections/refactor-artifacts.md +0 -17
- package/bundled/dev-pipeline/templates/sections/refactor-session-status.md +0 -28
- package/bundled/dev-pipeline/templates/sections/test-failure-recovery-agent.md +0 -52
- package/bundled/dev-pipeline/templates/sections/test-failure-recovery-lite.md +0 -52
- package/bundled/skills/prizmkit-code-review/references/workflow-state-protocol.md +0 -174
- package/bundled/skills/prizmkit-committer/references/workflow-state-protocol.md +0 -174
- package/bundled/skills/prizmkit-implement/references/workflow-state-protocol.md +0 -174
- package/bundled/skills/prizmkit-plan/references/workflow-state-protocol.md +0 -174
- package/bundled/skills/prizmkit-retrospective/references/workflow-state-protocol.md +0 -174
- package/bundled/skills/prizmkit-test/references/external-contract-mock-guidance.md +0 -119
|
@@ -75,7 +75,7 @@ Priority:
|
|
|
75
75
|
2. Existing config: `.prizmkit/deploy/deploy.config.json`
|
|
76
76
|
3. Project files: `vercel.json`, `netlify.toml`, `fly.toml`, `Dockerfile`, `docker-compose.yml`, GitHub deploy workflow, `app.yaml`, `serverless.yml`
|
|
77
77
|
4. Interactive question: ask where the project should be deployed
|
|
78
|
-
5. Headless with missing target: exit `NEEDS_INPUT` and write pending
|
|
78
|
+
5. Headless with missing target: exit `NEEDS_INPUT` and atomically write `.prizmkit/deploy/pending-input.json` conforming to `${SKILL_DIR}/references/pending-input-schema.json`
|
|
79
79
|
|
|
80
80
|
## Adapter Routing
|
|
81
81
|
|
|
@@ -99,7 +99,8 @@ Headless mode:
|
|
|
99
99
|
- Never wait for user input.
|
|
100
100
|
- May target only dev or test environments.
|
|
101
101
|
- Reject production with `ENVIRONMENT_DENIED`.
|
|
102
|
-
- If required info is missing, exit `NEEDS_INPUT` and write `.prizmkit/deploy/pending-input.json`.
|
|
102
|
+
- If required info is missing, exit `NEEDS_INPUT` and atomically write `.prizmkit/deploy/pending-input.json` from `${SKILL_DIR}/references/pending-input-schema.json`. Include only unanswered non-secret configuration questions, replace stale pending content on each attempt, and delete the file after those inputs are resolved and persisted.
|
|
103
|
+
- Never request passwords, tokens, private keys, connection strings, or other secret values through `pending-input.json`.
|
|
103
104
|
- Perform only actions already authorized by `deploy.config.json`.
|
|
104
105
|
|
|
105
106
|
## Command Routing
|
|
@@ -126,20 +127,33 @@ No-arg behavior:
|
|
|
126
127
|
|
|
127
128
|
## Artifact Structure
|
|
128
129
|
|
|
129
|
-
|
|
130
|
+
Managed deployment artifacts live under `.prizmkit/deploy/`:
|
|
130
131
|
|
|
131
132
|
```text
|
|
132
133
|
.prizmkit/deploy/
|
|
133
134
|
deploy.md
|
|
134
135
|
deploy.config.json
|
|
135
|
-
pending-input.json
|
|
136
|
+
pending-input.json # present only while non-secret input is unresolved
|
|
136
137
|
deploy-history/
|
|
137
|
-
|
|
138
|
-
secrets.enc.json
|
|
139
|
-
secrets.local.json
|
|
138
|
+
secrets.local.env # optional, ignored, permission-restricted dotenv data
|
|
140
139
|
```
|
|
141
140
|
|
|
142
|
-
Read
|
|
141
|
+
Read `${SKILL_DIR}/references/deploy-config-schema.md` when writing or validating config, `${SKILL_DIR}/references/deploy-history-schema.md` when writing history records, `${SKILL_DIR}/references/pending-input-schema.json` when writing unresolved questions, and `${SKILL_DIR}/assets/deploy-document-template.md` whenever creating or updating `deploy.md`.
|
|
142
|
+
|
|
143
|
+
`secrets.local.env` contains dotenv `KEY=value` lines, never JSON. Verify an exact ignore rule and current-user-only permissions before writing it. Encrypted-secret files and generated deployment scripts are not supported artifacts; do not advertise or create them.
|
|
144
|
+
|
|
145
|
+
Other files are generated only through these explicit target-native contracts:
|
|
146
|
+
|
|
147
|
+
| Output | Naming/content contract |
|
|
148
|
+
|---|---|
|
|
149
|
+
| `.github/workflows/deploy.yml` | `references/ci-cd-workflows.md` |
|
|
150
|
+
| `vercel.json`, `netlify.toml`, `fly.toml` | `references/cloud-platform-deploy.md`; generate only the selected platform file |
|
|
151
|
+
| `deploy-<releaseId>.tar.gz` | `references/direct-upload.md` or CI workflow template |
|
|
152
|
+
| `/etc/nginx/sites-available/<project>` | `references/nginx-blue-green.md` managed template and marker |
|
|
153
|
+
| `<server-project>/shared/.env.production` | strict permission-restricted dotenv contract in `references/ssh-adapter-flow.md` |
|
|
154
|
+
| `<server-project>/shared/deploy-metadata.json` | `references/deploy-metadata-schema.json` |
|
|
155
|
+
|
|
156
|
+
Do not generate another framework-owned deployment file until its deterministic identity, writer, update/overwrite policy, secret boundary, and complete content contract are added here.
|
|
143
157
|
|
|
144
158
|
Reference index:
|
|
145
159
|
- `references/ssh-adapter-flow.md` — load when routing to SSH Linux full automation.
|
|
@@ -149,6 +163,8 @@ Reference index:
|
|
|
149
163
|
- `references/dns-setup.md`, `references/ssl-setup.md` — load for domain and HTTPS setup.
|
|
150
164
|
- `references/ssh-execution-flow.md`, `references/nginx-blue-green.md`, `references/ssh-takeover.md` — load for deploy execution, traffic switching, rollback, or takeover.
|
|
151
165
|
- `references/cloud-platform-deploy.md`, `references/docker-deploy.md` — load for non-SSH guided routes.
|
|
166
|
+
- `references/pending-input-schema.json`, `assets/deploy-document-template.md` — load for managed pending-input and deployment-document writes.
|
|
167
|
+
- `references/deploy-metadata-schema.json` — load for atomic server active-slot metadata writes after verified SSH deploy/rollback operations.
|
|
152
168
|
- `references/live-validation-notes.md` — load when troubleshooting bootstrap or deploy failures.
|
|
153
169
|
|
|
154
170
|
Never record raw secret values in config, docs, or history. Secret presence metadata is allowed; raw values and unsalted hashes are not.
|
|
@@ -179,7 +195,7 @@ Key invariants:
|
|
|
179
195
|
Cloud platforms:
|
|
180
196
|
- Read `references/cloud-platform-deploy.md`.
|
|
181
197
|
- Detect required CLI/account steps.
|
|
182
|
-
- Generate or update deploy
|
|
198
|
+
- Generate or update config and render `deploy.md` from `${SKILL_DIR}/assets/deploy-document-template.md` without duplicate headings.
|
|
183
199
|
- Guide the user through interactive login or dashboard steps when needed.
|
|
184
200
|
|
|
185
201
|
Docker:
|
|
@@ -193,8 +209,8 @@ Docker:
|
|
|
193
209
|
When no adapter covers the detected target/project type:
|
|
194
210
|
|
|
195
211
|
1. Detect what you can: language, framework, build/start commands, env vars, port usage, databases.
|
|
196
|
-
2.
|
|
197
|
-
3. Record adapter gap in deploy history
|
|
212
|
+
2. Render `.prizmkit/deploy/deploy.md` from `${SKILL_DIR}/assets/deploy-document-template.md`, filling prerequisites, environment-variable names, build/start instructions, health checks, rollback limits, and manual actions.
|
|
213
|
+
3. Record adapter gap in deploy history using the event identity and content contract in `${SKILL_DIR}/references/deploy-history-schema.md`: missing adapter, detected project type, target, and fallback output.
|
|
198
214
|
4. Offer to generate basic CI/CD config when applicable.
|
|
199
215
|
|
|
200
216
|
## Validation
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# Deployment Document Template
|
|
2
|
+
|
|
3
|
+
Render `.prizmkit/deploy/deploy.md` with the exact top-level headings below. Replace placeholders with established values, use `not configured` or `not applicable` when truthful, and never write raw secret values. Update sections in place; do not append duplicate headings or turn this document into deployment history. Immutable operation events belong in `deploy-history/`.
|
|
4
|
+
|
|
5
|
+
```markdown
|
|
6
|
+
# Deployment
|
|
7
|
+
|
|
8
|
+
## Target
|
|
9
|
+
|
|
10
|
+
- Project: <project name>
|
|
11
|
+
- Project type: <detected project type>
|
|
12
|
+
- Environment: <dev | test | production>
|
|
13
|
+
- Target: <SSH host alias | cloud platform | Docker | unsupported target>
|
|
14
|
+
- Adapter: <ssh | cloud-guided | docker-guided | documented-fallback>
|
|
15
|
+
- Strategy: <push | pull | direct-upload | platform-native | container-native | manual>
|
|
16
|
+
- Public URL: <URL | not configured>
|
|
17
|
+
|
|
18
|
+
## Prerequisites
|
|
19
|
+
|
|
20
|
+
- <required runtime/tool/account/connectivity prerequisite>
|
|
21
|
+
|
|
22
|
+
## Required Environment Variables
|
|
23
|
+
|
|
24
|
+
Record names, purpose, source, and presence only. Never record values.
|
|
25
|
+
|
|
26
|
+
| Name | Required | Purpose | Secret Source | Present |
|
|
27
|
+
|---|---|---|---|---|
|
|
28
|
+
| `<VARIABLE_NAME>` | yes | <purpose> | <platform secret store or ignored local env file> | yes/no |
|
|
29
|
+
|
|
30
|
+
## Build and Release
|
|
31
|
+
|
|
32
|
+
- Install command: `<command | not required>`
|
|
33
|
+
- Build command: `<command | not required>`
|
|
34
|
+
- Start command: `<command>`
|
|
35
|
+
- Release layout: <path/layout or platform-native>
|
|
36
|
+
- Artifact source: <repository checkout | uploaded archive | container image | platform build>
|
|
37
|
+
|
|
38
|
+
## Runtime
|
|
39
|
+
|
|
40
|
+
- Process manager: <manager | platform-native>
|
|
41
|
+
- Runtime user: <user | platform-managed>
|
|
42
|
+
- Internal port: <port | platform-managed>
|
|
43
|
+
- Public routing: <Nginx/proxy/platform route>
|
|
44
|
+
- Persistent storage: <mounts/volumes | none>
|
|
45
|
+
|
|
46
|
+
## Health Checks
|
|
47
|
+
|
|
48
|
+
| Name | URL or Command | Expected | Last Verified Result |
|
|
49
|
+
|---|---|---|---|
|
|
50
|
+
| <check> | <path/command> | <status/output> | <pass/fail/not run> |
|
|
51
|
+
|
|
52
|
+
## DNS and TLS
|
|
53
|
+
|
|
54
|
+
- Domain: <domain | not configured>
|
|
55
|
+
- DNS status: <configured/pending/not applicable>
|
|
56
|
+
- TLS issuer: <issuer | platform-managed | not configured>
|
|
57
|
+
- Renewal: <automatic/manual/not applicable>
|
|
58
|
+
|
|
59
|
+
## Rollback
|
|
60
|
+
|
|
61
|
+
- Strategy: <previous release/platform rollback/image rollback/manual>
|
|
62
|
+
- Command or procedure: <safe rollback command/procedure>
|
|
63
|
+
- Readiness: <verified/not verified/not applicable>
|
|
64
|
+
|
|
65
|
+
## Operations
|
|
66
|
+
|
|
67
|
+
- Status: `<command or platform action>`
|
|
68
|
+
- Logs: `<command or platform action>`
|
|
69
|
+
- Restart: `<command or platform action>`
|
|
70
|
+
- Health: `<command or platform action>`
|
|
71
|
+
- Rollback: `<command or platform action>`
|
|
72
|
+
|
|
73
|
+
## Current Validation
|
|
74
|
+
|
|
75
|
+
- Configuration: <pass/fail/not run>
|
|
76
|
+
- Connectivity: <pass/fail/not run>
|
|
77
|
+
- Build: <pass/fail/not run>
|
|
78
|
+
- Staged health: <pass/fail/not run>
|
|
79
|
+
- Live health: <pass/fail/not run>
|
|
80
|
+
- Latest history record: `.prizmkit/deploy/deploy-history/<event-id>.json` or `none`
|
|
81
|
+
|
|
82
|
+
## Manual Actions
|
|
83
|
+
|
|
84
|
+
- <remaining user-owned action, or `None`>
|
|
85
|
+
|
|
86
|
+
## Notes
|
|
87
|
+
|
|
88
|
+
- <stable deployment constraint, adapter gap, or operational warning>
|
|
89
|
+
```
|
|
@@ -43,6 +43,9 @@ jobs:
|
|
|
43
43
|
with:
|
|
44
44
|
node-version: 20
|
|
45
45
|
|
|
46
|
+
- name: Allocate Release Identity
|
|
47
|
+
run: echo "ARCHIVE_ID=$(date -u +%Y%m%dT%H%M%SZ)-$(git rev-parse --short=12 HEAD)" >> "$GITHUB_ENV"
|
|
48
|
+
|
|
46
49
|
- name: Install & Build
|
|
47
50
|
run: |
|
|
48
51
|
npm ci
|
|
@@ -50,26 +53,35 @@ jobs:
|
|
|
50
53
|
|
|
51
54
|
- name: Package & Transfer
|
|
52
55
|
run: |
|
|
53
|
-
|
|
54
|
-
tar czf deploy-$RELEASE_ID.tar.gz \
|
|
56
|
+
tar czf deploy-$ARCHIVE_ID.tar.gz \
|
|
55
57
|
<build-output-dir>/ node_modules/ package.json package-lock.json
|
|
56
|
-
scp -P ${{ secrets.SSH_PORT }} deploy-$
|
|
58
|
+
scp -P ${{ secrets.SSH_PORT }} deploy-$ARCHIVE_ID.tar.gz \
|
|
57
59
|
${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }}:/var/www/<project>/releases/
|
|
58
60
|
|
|
59
61
|
- name: Deploy on Server
|
|
60
62
|
uses: appleboy/ssh-action@v1
|
|
63
|
+
env:
|
|
64
|
+
ARCHIVE_ID: ${{ env.ARCHIVE_ID }}
|
|
61
65
|
with:
|
|
62
66
|
host: ${{ secrets.SSH_HOST }}
|
|
63
67
|
username: ${{ secrets.SSH_USER }}
|
|
64
68
|
key: ${{ secrets.SSH_KEY }}
|
|
65
69
|
port: ${{ secrets.SSH_PORT }}
|
|
70
|
+
envs: ARCHIVE_ID
|
|
66
71
|
script: |
|
|
72
|
+
set -eu
|
|
67
73
|
cd /var/www/<project>
|
|
68
|
-
RELEASE_ID
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
74
|
+
RELEASE_ID="$ARCHIVE_ID"
|
|
75
|
+
SUFFIX=1
|
|
76
|
+
while [ -e "releases/$RELEASE_ID" ]; do
|
|
77
|
+
[ "$SUFFIX" -le 99 ] || { echo "release identity suffixes exhausted" >&2; exit 1; }
|
|
78
|
+
RELEASE_ID="$ARCHIVE_ID-$(printf '%02d' "$SUFFIX")"
|
|
79
|
+
SUFFIX=$((SUFFIX + 1))
|
|
80
|
+
done
|
|
81
|
+
mkdir "releases/$RELEASE_ID"
|
|
82
|
+
tar xzf "releases/deploy-$ARCHIVE_ID.tar.gz" -C "releases/$RELEASE_ID"
|
|
83
|
+
rm "releases/deploy-$ARCHIVE_ID.tar.gz"
|
|
84
|
+
# PM2 start, health check, Nginx switch, history, and metadata use RELEASE_ID
|
|
73
85
|
```
|
|
74
86
|
|
|
75
87
|
**Key difference from Pull:** the runner checks out code, installs, builds, and only transmits the result. The server doesn't need Git or build tools — just Node.js runtime and PM2.
|
|
@@ -91,23 +103,41 @@ jobs:
|
|
|
91
103
|
deploy:
|
|
92
104
|
runs-on: ubuntu-latest
|
|
93
105
|
steps:
|
|
106
|
+
- uses: actions/checkout@v4
|
|
107
|
+
|
|
108
|
+
- name: Allocate Release Identity
|
|
109
|
+
run: |
|
|
110
|
+
echo "RELEASE_BASE=$(date -u +%Y%m%dT%H%M%SZ)-$(git rev-parse --short=12 HEAD)" >> "$GITHUB_ENV"
|
|
111
|
+
echo "DEPLOY_SHA=$(git rev-parse HEAD)" >> "$GITHUB_ENV"
|
|
112
|
+
|
|
94
113
|
- name: Trigger Server Deploy
|
|
95
114
|
uses: appleboy/ssh-action@v1
|
|
115
|
+
env:
|
|
116
|
+
RELEASE_BASE: ${{ env.RELEASE_BASE }}
|
|
117
|
+
DEPLOY_SHA: ${{ env.DEPLOY_SHA }}
|
|
96
118
|
with:
|
|
97
119
|
host: ${{ secrets.SSH_HOST }}
|
|
98
120
|
username: ${{ secrets.SSH_USER }}
|
|
99
121
|
key: ${{ secrets.SSH_KEY }}
|
|
100
122
|
port: ${{ secrets.SSH_PORT }}
|
|
123
|
+
envs: RELEASE_BASE,DEPLOY_SHA
|
|
101
124
|
script: |
|
|
125
|
+
set -eu
|
|
102
126
|
cd /var/www/<project>
|
|
103
|
-
RELEASE_ID
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
127
|
+
RELEASE_ID="$RELEASE_BASE"
|
|
128
|
+
SUFFIX=1
|
|
129
|
+
while [ -e "releases/$RELEASE_ID" ]; do
|
|
130
|
+
[ "$SUFFIX" -le 99 ] || { echo "release identity suffixes exhausted" >&2; exit 1; }
|
|
131
|
+
RELEASE_ID="$RELEASE_BASE-$(printf '%02d' "$SUFFIX")"
|
|
132
|
+
SUFFIX=$((SUFFIX + 1))
|
|
133
|
+
done
|
|
134
|
+
git clone --no-checkout --branch <branch> <repoUrl> "releases/$RELEASE_ID"
|
|
135
|
+
git -C "releases/$RELEASE_ID" checkout --detach "$DEPLOY_SHA"
|
|
136
|
+
cd "releases/$RELEASE_ID"
|
|
107
137
|
npm ci
|
|
108
|
-
cp
|
|
138
|
+
cp ../../shared/.env.production .
|
|
109
139
|
npm run build
|
|
110
|
-
# PM2 start, health check, Nginx switch
|
|
140
|
+
# PM2 start, health check, Nginx switch, history, and metadata use RELEASE_ID
|
|
111
141
|
```
|
|
112
142
|
|
|
113
143
|
**Key difference from Push:** the workflow is simpler (one step: SSH + run script), but the server needs Git, full build toolchain, and must be able to reach the repo.
|
|
@@ -40,7 +40,23 @@ Platform rollback is instant — no release-based rollback needed.
|
|
|
40
40
|
|
|
41
41
|
### Vercel
|
|
42
42
|
|
|
43
|
-
Vercel auto-detects Next.js projects — no config file
|
|
43
|
+
Vercel auto-detects Next.js projects — no config file is generated for basic deployments. When confirmed custom routing or static build settings require `vercel.json`, start from this minimal platform-native shape and include only established keys:
|
|
44
|
+
|
|
45
|
+
```json
|
|
46
|
+
{
|
|
47
|
+
"$schema": "https://openapi.vercel.sh/vercel.json",
|
|
48
|
+
"buildCommand": "npm run build",
|
|
49
|
+
"outputDirectory": "dist",
|
|
50
|
+
"rewrites": [
|
|
51
|
+
{
|
|
52
|
+
"source": "/(.*)",
|
|
53
|
+
"destination": "/index.html"
|
|
54
|
+
}
|
|
55
|
+
]
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Omit `buildCommand`/`outputDirectory` when framework detection owns them, and omit `rewrites` unless the application actually needs SPA fallback or a confirmed route. Validate generated configuration with the installed Vercel CLI before deployment.
|
|
44
60
|
|
|
45
61
|
Key behaviors:
|
|
46
62
|
- Next.js: framework auto-detected, build command and output directory inferred automatically
|
|
@@ -77,7 +93,7 @@ app = "<app-name>"
|
|
|
77
93
|
primary_region = "lhr"
|
|
78
94
|
|
|
79
95
|
[build]
|
|
80
|
-
|
|
96
|
+
dockerfile = "Dockerfile"
|
|
81
97
|
|
|
82
98
|
[http_service]
|
|
83
99
|
internal_port = 3000
|
|
@@ -85,7 +101,7 @@ primary_region = "lhr"
|
|
|
85
101
|
```
|
|
86
102
|
|
|
87
103
|
Key behaviors:
|
|
88
|
-
-
|
|
104
|
+
- Build source: `dockerfile = "Dockerfile"` for project-owned images, or a confirmed platform-supported image/build configuration; static sites still need a valid serving image rather than an invented `static` builder value
|
|
89
105
|
- Secrets: `fly secrets set <KEY>=<VALUE>` for runtime environment variables
|
|
90
106
|
- Scale: `fly scale count <N>` to adjust VM instances
|
|
91
107
|
- Volumes: for persistent data, configure `[mounts]` in fly.toml
|
|
@@ -12,12 +12,13 @@ During Discovery Step 1 (Project Detection), database drivers were already scann
|
|
|
12
12
|
|
|
13
13
|
## Secrets file safety
|
|
14
14
|
|
|
15
|
-
Before writing `.prizmkit/deploy/secrets.local.
|
|
15
|
+
Before writing `.prizmkit/deploy/secrets.local.env`:
|
|
16
16
|
|
|
17
|
-
1. Verify `.gitignore` or an equivalent ignore rule covers `.prizmkit/deploy/secrets.local.
|
|
18
|
-
2. If the ignore rule is missing, pause and add or request
|
|
19
|
-
3.
|
|
20
|
-
4.
|
|
17
|
+
1. Verify `.gitignore` or an equivalent ignore rule covers the exact `.prizmkit/deploy/secrets.local.env` path or a compatible `.prizmkit/deploy/*.local.env` pattern.
|
|
18
|
+
2. If the ignore rule is missing, pause and add or request it before writing secrets.
|
|
19
|
+
3. Create/update the file with restrictive creation permissions (for example `umask 077` on POSIX), atomically replace it without widening permissions, set mode `600`, and verify it is ignored by Git.
|
|
20
|
+
4. Use dotenv syntax: one `KEY=value` assignment per line, UTF-8, no JSON braces or commas. Preserve unrelated existing assignments and reject malformed or duplicate keys.
|
|
21
|
+
5. Record only presence metadata in deploy config, docs, reports, and history. Never copy raw passwords, connection strings, passphrases, decryption keys, unsalted hashes, or full env var values into committed files.
|
|
21
22
|
|
|
22
23
|
```
|
|
23
24
|
apt-get install -y postgresql postgresql-contrib
|
|
@@ -26,10 +27,19 @@ sudo -u postgres psql -c "CREATE USER <project> WITH PASSWORD '<random-password>
|
|
|
26
27
|
sudo -u postgres psql -c "GRANT ALL ON DATABASE <project> TO <project>;"
|
|
27
28
|
```
|
|
28
29
|
|
|
29
|
-
- Generate a secure
|
|
30
|
-
- Write the
|
|
31
|
-
-
|
|
32
|
-
- In deploy.md
|
|
30
|
+
- Generate a cryptographically secure 32-character URL-safe password using letters, digits, `_`, and `-`, with no whitespace, quotes, `#`, or `=`.
|
|
31
|
+
- Write or replace the single dotenv assignment `DATABASE_URL=postgresql://<project>:<password>@localhost:5432/<project>` in `.prizmkit/deploy/secrets.local.env`.
|
|
32
|
+
- Re-verify ignore status and current-user-only permissions after atomic replacement.
|
|
33
|
+
- In `deploy.md`, record only: "PostgreSQL connection information is stored in ignored local secret storage; raw values are not committed."
|
|
34
|
+
|
|
35
|
+
## Legacy Local-Secret Migration
|
|
36
|
+
|
|
37
|
+
If `.prizmkit/deploy/secrets.local.json` already exists from an earlier installation, treat the filename as legacy input only, never as a current output:
|
|
38
|
+
|
|
39
|
+
1. Verify it is ignored by Git and restricted to the current user before reading it.
|
|
40
|
+
2. Detect either a JSON object containing string values or strict dotenv `KEY=value` lines; reject mixed, malformed, duplicate, or non-string content without printing values.
|
|
41
|
+
3. Convert the validated assignments to `.prizmkit/deploy/secrets.local.env` through the restrictive atomic-write rules above.
|
|
42
|
+
4. Compare key names and presence only. Remove the legacy file only after successful conversion and explicit user confirmation; otherwise leave it untouched and report migration pending.
|
|
33
43
|
|
|
34
44
|
## MySQL setup (future)
|
|
35
45
|
|
|
@@ -44,12 +54,12 @@ redis-cli CONFIG REWRITE
|
|
|
44
54
|
```
|
|
45
55
|
|
|
46
56
|
- Bind to localhost only (modify `/etc/redis/redis.conf` if needed).
|
|
47
|
-
- Write `REDIS_URL=redis://:<password>@localhost:6379`
|
|
48
|
-
-
|
|
57
|
+
- Write or replace the single dotenv assignment `REDIS_URL=redis://:<password>@localhost:6379` in `.prizmkit/deploy/secrets.local.env` using the same URL-safe password and atomic permission rules.
|
|
58
|
+
- Re-verify ignore status and current-user-only permissions after replacement.
|
|
49
59
|
|
|
50
60
|
## Security notes
|
|
51
61
|
|
|
52
62
|
- Never write database passwords to deploy.md, because deploy.md may be committed to git and passwords would leak.
|
|
53
|
-
- Passwords stored in `.prizmkit/deploy/secrets.local.
|
|
63
|
+
- Passwords are stored only in `.prizmkit/deploy/secrets.local.env` after verifying the file is ignored by Git and locked down to current-user read/write permissions.
|
|
54
64
|
- Default: database binds to localhost, no external access, because most indie projects only need local connections.
|
|
55
65
|
- Record a `"database-setup"` event in deploy history (presence metadata only, no passwords).
|
|
@@ -26,12 +26,14 @@ This file is the machine-readable deployment configuration. Always read it befor
|
|
|
26
26
|
{
|
|
27
27
|
"releaseRetention": 5,
|
|
28
28
|
"credentialMode": "ai-assisted|user-managed",
|
|
29
|
-
"secretStorage": "ask-every-time|
|
|
29
|
+
"secretStorage": "ask-every-time|ignored-local-env|user-managed-on-server-only",
|
|
30
30
|
"rollbackOnFailure": true,
|
|
31
31
|
"headlessDefaultEnvironment": "test"
|
|
32
32
|
}
|
|
33
33
|
```
|
|
34
34
|
|
|
35
|
+
`ignored-local-env` means `.prizmkit/deploy/secrets.local.env` after exact ignore and permission verification. Legacy `plaintext-local` may be migrated only through the local-secret migration contract. Legacy `encrypted-local` is unsupported because this Skill has no encryption/key-management implementation; block deployment and require the user to select a supported mode without exposing secret values.
|
|
36
|
+
|
|
35
37
|
## environments
|
|
36
38
|
|
|
37
39
|
Keyed by environment name. Each entry:
|
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
# Deploy History Record Schema
|
|
2
2
|
|
|
3
|
-
Each event
|
|
3
|
+
Each immutable event is written atomically to `.prizmkit/deploy/deploy-history/<eventId>.json`. The filename stem must equal the JSON `eventId` exactly.
|
|
4
4
|
|
|
5
5
|
```json
|
|
6
6
|
{
|
|
7
|
-
"eventId": "
|
|
8
|
-
"eventType": "deploy|rollback|status|validation|failed-deploy|user-aborted|takeover|adapter-gap",
|
|
9
|
-
"timestamp": "<ISO 8601>",
|
|
7
|
+
"eventId": "deploy-20260430T142233Z-22783a3",
|
|
8
|
+
"eventType": "deploy|rollback|status|validation|failed-deploy|user-aborted|takeover|adapter-gap|database-setup",
|
|
9
|
+
"timestamp": "<ISO 8601 UTC>",
|
|
10
|
+
"releaseId": "20260430T142233Z-22783a3 or null",
|
|
10
11
|
"serverId": "<server id from deploy.config.json>",
|
|
11
12
|
"appIds": ["<app ids involved>"],
|
|
12
13
|
"branch": "<git branch>",
|
|
13
14
|
"commitSha": "<full or short commit SHA>",
|
|
14
|
-
"releasePath": "<full server path, e.g. /var/www/prizm-ideas/releases/
|
|
15
|
+
"releasePath": "<full server path, e.g. /var/www/prizm-ideas/releases/20260430T142233Z-22783a3>",
|
|
15
16
|
"previousReleasePath": "<previous release path or null for first deploy>",
|
|
16
17
|
"targetPort": 3101,
|
|
17
18
|
"targetColor": "blue|green",
|
|
@@ -45,9 +46,24 @@ Each event in `.prizmkit/deploy/deploy-history/<id>.json` follows this schema:
|
|
|
45
46
|
}
|
|
46
47
|
```
|
|
47
48
|
|
|
49
|
+
## Event and File Identity
|
|
50
|
+
|
|
51
|
+
Generate every `eventId` as:
|
|
52
|
+
|
|
53
|
+
```text
|
|
54
|
+
<event-type>-<UTC-compact-timestamp>-<short-sha-or-none>[-NN]
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Rules:
|
|
58
|
+
|
|
59
|
+
- `UTC-compact-timestamp` is the event time formatted `YYYYMMDDTHHMMSSZ`.
|
|
60
|
+
- `short-sha` is the lowercase 7-12 hexadecimal commit prefix when a commit exists; otherwise use literal `none`.
|
|
61
|
+
- If the candidate filename already exists, append the lowest available two-digit suffix from `-01` through `-99`; never overwrite a history record. If all suffixes are occupied, stop with a recording error.
|
|
62
|
+
- Use the exact event ID as the filename stem. Example: `rollback-20260430T151000Z-22783a3.json`.
|
|
63
|
+
- `releaseId` is a separate deployment/release-directory identity. Set it to the affected release for deploy, failed-deploy, and rollback events; otherwise use `null` when no release applies.
|
|
64
|
+
|
|
48
65
|
## Field Notes
|
|
49
66
|
|
|
50
|
-
- `eventId`: Use `<releaseId>` for deploy events, `<releaseId>-rollback` for rollbacks.
|
|
51
67
|
- `eventType`: Use `failed-deploy` when deploy fails before traffic switch, `deploy` when it succeeds. Use `adapter-gap` when no adapter exists for the detected project type or target — include `detectedProjectType`, `missingAdapter`, and `fallbackOutput` in the record.
|
|
52
68
|
- `phases`: Only include phases that were attempted. Skip phases that were never reached.
|
|
53
69
|
- `healthCheckResults`: Include all configured health checks. `pass` = actual status matches one of the expected status codes.
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"title": "PrizmKit Server Deployment Metadata",
|
|
4
|
+
"type": "object",
|
|
5
|
+
"additionalProperties": false,
|
|
6
|
+
"required": [
|
|
7
|
+
"schema_version",
|
|
8
|
+
"activeColor",
|
|
9
|
+
"activePort",
|
|
10
|
+
"lastReleaseId",
|
|
11
|
+
"lastOperationEventId",
|
|
12
|
+
"updatedAt"
|
|
13
|
+
],
|
|
14
|
+
"properties": {
|
|
15
|
+
"schema_version": {
|
|
16
|
+
"const": 1
|
|
17
|
+
},
|
|
18
|
+
"activeColor": {
|
|
19
|
+
"enum": ["blue", "green"]
|
|
20
|
+
},
|
|
21
|
+
"activePort": {
|
|
22
|
+
"type": "integer",
|
|
23
|
+
"minimum": 1,
|
|
24
|
+
"maximum": 65535
|
|
25
|
+
},
|
|
26
|
+
"lastReleaseId": {
|
|
27
|
+
"type": "string",
|
|
28
|
+
"pattern": "^[0-9]{8}T[0-9]{6}Z-[0-9a-f]{7,12}(?:-[0-9]{2})?$"
|
|
29
|
+
},
|
|
30
|
+
"lastOperationEventId": {
|
|
31
|
+
"type": "string",
|
|
32
|
+
"pattern": "^[a-z][a-z-]*-[0-9]{8}T[0-9]{6}Z-(?:[0-9a-f]{7,12}|none)(?:-[0-9]{2})?$"
|
|
33
|
+
},
|
|
34
|
+
"updatedAt": {
|
|
35
|
+
"type": "string",
|
|
36
|
+
"format": "date-time"
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
"examples": [
|
|
40
|
+
{
|
|
41
|
+
"schema_version": 1,
|
|
42
|
+
"activeColor": "blue",
|
|
43
|
+
"activePort": 3101,
|
|
44
|
+
"lastReleaseId": "20260430T142233Z-22783a3",
|
|
45
|
+
"lastOperationEventId": "deploy-20260430T142233Z-22783a3",
|
|
46
|
+
"updatedAt": "2026-04-30T14:22:33Z"
|
|
47
|
+
}
|
|
48
|
+
]
|
|
49
|
+
}
|
|
@@ -12,7 +12,7 @@ These findings from the first PrizmKit deployment (PrizmIdeas) guide edge-case h
|
|
|
12
12
|
|
|
13
13
|
5. **`pm2 startup` needs explicit PATH.** Always use `env PATH=$PATH:/usr/bin pm2 startup ...`, because the pm2 binary may not be on root's default PATH.
|
|
14
14
|
|
|
15
|
-
6. **Persist deploy metadata on server.**
|
|
15
|
+
6. **Persist deploy metadata on server.** After public health and history recording succeed, atomically write `shared/deploy-metadata.json` from `${SKILL_DIR}/references/deploy-metadata-schema.json`, including active color/port, release identity, operation event identity, and UTC update time. Subsequent deploys and rollbacks depend on this active-slot record.
|
|
16
16
|
|
|
17
17
|
7. **Detect first deployment.** If no `current` symlink and no PM2 process for the app, skip rollback safety checks and use blue (3101) as initial color.
|
|
18
18
|
|