prizmkit 1.1.79 → 1.1.80
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/dev-pipeline/scripts/init-pipeline.py +2 -0
- package/bundled/dev-pipeline-windows/scripts/init-pipeline.py +2 -0
- package/bundled/skills/_metadata.json +1 -1
- package/bundled/skills/app-planner/SKILL.md +10 -347
- package/bundled/skills/app-planner/references/infrastructure-convention-discovery.md +108 -0
- package/bundled/skills/app-planner/references/project-conventions-discovery.md +59 -0
- package/bundled/skills/app-planner/references/project-state-detection.md +88 -0
- package/bundled/skills/app-planner/references/rules-configuration.md +46 -0
- package/bundled/skills/bug-fix-workflow/SKILL.md +1 -30
- package/bundled/skills/bug-fix-workflow/references/bug-diagnosis.md +66 -0
- package/bundled/skills/bugfix-pipeline-launcher/SKILL.md +3 -40
- package/bundled/skills/bugfix-pipeline-launcher/references/configuration.md +49 -0
- package/bundled/skills/feature-pipeline-launcher/SKILL.md +3 -46
- package/bundled/skills/feature-pipeline-launcher/references/configuration.md +55 -0
- package/bundled/skills/feature-workflow/SKILL.md +5 -121
- package/bundled/skills/feature-workflow/references/brainstorm-guide.md +137 -0
- package/bundled/skills/prizm-kit/SKILL.md +11 -0
- package/bundled/skills/prizmkit-code-review/SKILL.md +66 -135
- package/bundled/skills/prizmkit-code-review/references/dev-agent-prompt.md +30 -0
- package/bundled/skills/prizmkit-code-review/references/review-report-template.md +31 -0
- package/bundled/skills/prizmkit-code-review/references/reviewer-agent-prompt.md +62 -0
- package/bundled/skills/prizmkit-code-review/scripts/check_loop.py +186 -0
- package/bundled/skills/prizmkit-committer/SKILL.md +6 -0
- package/bundled/skills/prizmkit-deploy/SKILL.md +48 -72
- package/bundled/skills/prizmkit-deploy/references/data-safety-examples.md +120 -0
- package/bundled/skills/prizmkit-deploy/references/ssh-bootstrap-flow.md +49 -0
- package/bundled/skills/prizmkit-deploy/references/ssh-execution-flow.md +41 -0
- package/bundled/skills/prizmkit-deploy/references/ssh-takeover.md +20 -0
- package/bundled/skills/prizmkit-implement/SKILL.md +6 -0
- package/bundled/skills/prizmkit-plan/SKILL.md +1 -83
- package/bundled/skills/prizmkit-plan/references/examples.md +85 -0
- package/bundled/skills/prizmkit-prizm-docs/SKILL.md +13 -0
- package/bundled/skills/prizmkit-test/SKILL.md +3 -151
- package/bundled/skills/prizmkit-test/references/examples.md +70 -0
- package/bundled/skills/prizmkit-test/references/test-generation-steps.md +49 -0
- package/bundled/skills/prizmkit-test/references/test-report-template.md +42 -0
- package/bundled/skills/recovery-workflow/SKILL.md +1 -30
- package/bundled/skills/recovery-workflow/references/detection.md +58 -0
- package/bundled/skills/refactor-pipeline-launcher/SKILL.md +3 -45
- package/bundled/skills/refactor-pipeline-launcher/references/configuration.md +54 -0
- package/bundled/skills/refactor-planner/SKILL.md +9 -149
- package/bundled/skills/refactor-planner/references/fast-path.md +59 -0
- package/bundled/skills/refactor-planner/references/planning-phases.md +135 -0
- package/bundled/skills/refactor-workflow/SKILL.md +4 -103
- package/bundled/skills/refactor-workflow/references/brainstorm-guide.md +116 -0
- package/bundled/skills-windows/app-planner/SKILL.md +10 -349
- package/bundled/skills-windows/app-planner/references/infrastructure-convention-discovery.md +108 -0
- package/bundled/skills-windows/app-planner/references/project-conventions-discovery.md +59 -0
- package/bundled/skills-windows/app-planner/references/project-state-detection.md +90 -0
- package/bundled/skills-windows/app-planner/references/rules-configuration.md +46 -0
- package/bundled/skills-windows/bug-fix-workflow/SKILL.md +1 -30
- package/bundled/skills-windows/bug-fix-workflow/references/bug-diagnosis.md +66 -0
- package/bundled/skills-windows/bugfix-pipeline-launcher/SKILL.md +2 -29
- package/bundled/skills-windows/bugfix-pipeline-launcher/references/configuration.md +49 -0
- package/bundled/skills-windows/feature-pipeline-launcher/SKILL.md +2 -35
- package/bundled/skills-windows/feature-pipeline-launcher/references/configuration.md +55 -0
- package/bundled/skills-windows/feature-workflow/SKILL.md +5 -121
- package/bundled/skills-windows/feature-workflow/references/brainstorm-guide.md +137 -0
- package/bundled/skills-windows/prizm-kit/SKILL.md +11 -0
- package/bundled/skills-windows/prizmkit-code-review/SKILL.md +66 -135
- package/bundled/skills-windows/prizmkit-code-review/references/dev-agent-prompt.md +30 -0
- package/bundled/skills-windows/prizmkit-code-review/references/review-report-template.md +31 -0
- package/bundled/skills-windows/prizmkit-code-review/references/reviewer-agent-prompt.md +62 -0
- package/bundled/skills-windows/prizmkit-code-review/scripts/check_loop.py +186 -0
- package/bundled/skills-windows/prizmkit-committer/SKILL.md +6 -0
- package/bundled/skills-windows/prizmkit-deploy/SKILL.md +49 -73
- package/bundled/skills-windows/prizmkit-deploy/references/data-safety-examples.md +120 -0
- package/bundled/skills-windows/prizmkit-deploy/references/direct-upload.md +3 -3
- package/bundled/skills-windows/prizmkit-deploy/references/ssh-bootstrap-flow.md +49 -0
- package/bundled/skills-windows/prizmkit-deploy/references/ssh-execution-flow.md +41 -0
- package/bundled/skills-windows/prizmkit-deploy/references/ssh-takeover.md +20 -0
- package/bundled/skills-windows/prizmkit-deploy/references/ssl-setup.md +2 -2
- package/bundled/skills-windows/prizmkit-implement/SKILL.md +6 -0
- package/bundled/skills-windows/prizmkit-plan/SKILL.md +1 -83
- package/bundled/skills-windows/prizmkit-plan/references/examples.md +85 -0
- package/bundled/skills-windows/prizmkit-prizm-docs/SKILL.md +13 -0
- package/bundled/skills-windows/prizmkit-retrospective/references/structural-sync-steps.md +1 -1
- package/bundled/skills-windows/prizmkit-test/SKILL.md +3 -151
- package/bundled/skills-windows/prizmkit-test/references/examples.md +70 -0
- package/bundled/skills-windows/prizmkit-test/references/test-generation-steps.md +49 -0
- package/bundled/skills-windows/prizmkit-test/references/test-report-template.md +42 -0
- package/bundled/skills-windows/recovery-workflow/SKILL.md +1 -52
- package/bundled/skills-windows/recovery-workflow/references/detection.md +58 -0
- package/bundled/skills-windows/refactor-pipeline-launcher/SKILL.md +2 -32
- package/bundled/skills-windows/refactor-pipeline-launcher/references/configuration.md +54 -0
- package/bundled/skills-windows/refactor-planner/SKILL.md +9 -149
- package/bundled/skills-windows/refactor-planner/references/fast-path.md +59 -0
- package/bundled/skills-windows/refactor-planner/references/planning-phases.md +135 -0
- package/bundled/skills-windows/refactor-workflow/SKILL.md +4 -103
- package/bundled/skills-windows/refactor-workflow/references/brainstorm-guide.md +116 -0
- package/package.json +1 -1
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# Reviewer Agent Prompt Template
|
|
2
|
+
|
|
3
|
+
Used in Phase 1 Step 1 of `/prizmkit-code-review`. The orchestrator fills `{goals}`, `{plan decisions}`, `{dev rules}`, `{round N}`, and `{round_context}` before spawning the Reviewer Agent.
|
|
4
|
+
|
|
5
|
+
```
|
|
6
|
+
You are a code reviewer. Review workspace changes against the spec goals, plan decisions, and per-layer dev rules.
|
|
7
|
+
|
|
8
|
+
## Spec Goals
|
|
9
|
+
{goals and acceptance criteria from spec.md}
|
|
10
|
+
|
|
11
|
+
## Plan Decisions
|
|
12
|
+
{architecture decisions and task list from plan.md}
|
|
13
|
+
|
|
14
|
+
## Dev Rules (per-layer conventions)
|
|
15
|
+
{rules from .prizmkit/rules/<layer>-rules.md, or "No custom dev rules configured — use general best practices."}
|
|
16
|
+
|
|
17
|
+
## Review Round
|
|
18
|
+
Round {N}. {round_context}
|
|
19
|
+
|
|
20
|
+
## What to Review
|
|
21
|
+
Run these commands to see the current workspace changes:
|
|
22
|
+
- `git diff` (unstaged changes)
|
|
23
|
+
- `git diff --cached` (staged changes)
|
|
24
|
+
- `git status` (new/deleted files)
|
|
25
|
+
|
|
26
|
+
For new files shown in git status, read their full content.
|
|
27
|
+
For modified files, read enough surrounding context to understand the change.
|
|
28
|
+
|
|
29
|
+
## Review Dimensions
|
|
30
|
+
Evaluate the changes across these dimensions (focus on what's relevant):
|
|
31
|
+
|
|
32
|
+
1. **Goal alignment**: Do the changes accomplish all goals from spec.md? Anything missing or off-target?
|
|
33
|
+
2. **Defects**: Logic bugs, missing error handling, boundary condition issues, incorrect behavior.
|
|
34
|
+
3. **Completeness**: Files that should have been changed but weren't? Missing tests, types, imports, exports?
|
|
35
|
+
4. **Consistency**: Do changes follow the project's existing patterns, naming conventions, and code style?
|
|
36
|
+
5. **Security**: Hardcoded secrets, injection vulnerabilities, unsafe operations.
|
|
37
|
+
6. **Rules compliance**: (Skip this dimension if no dev rules were provided.) Do changes follow the per-layer dev rules? Flag violations of framework conventions, naming patterns, state management, or other rules defined for that layer.
|
|
38
|
+
|
|
39
|
+
## Output Format
|
|
40
|
+
Respond with EXACTLY this format:
|
|
41
|
+
|
|
42
|
+
### Result: PASS | NEEDS_FIXES
|
|
43
|
+
|
|
44
|
+
### Findings
|
|
45
|
+
(If PASS, write "No issues found.")
|
|
46
|
+
|
|
47
|
+
#### Finding N
|
|
48
|
+
- **Severity**: high | medium | low
|
|
49
|
+
- **Dimension**: goal-alignment | defect | completeness | consistency | security | rules-compliance
|
|
50
|
+
- **Location**: filepath:line (or "project-level")
|
|
51
|
+
- **Problem**: What is wrong and why it matters
|
|
52
|
+
- **Suggestion**: Recommended fix approach
|
|
53
|
+
- **Verification**: How to confirm the fix is correct
|
|
54
|
+
|
|
55
|
+
### Summary
|
|
56
|
+
One to two sentences about the overall state of the changes.
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Round Context
|
|
60
|
+
|
|
61
|
+
- Round 1: "This is the first review. Examine all changes comprehensively."
|
|
62
|
+
- Round 2+: "Previous round found issues that were fixed. Focus on: (1) whether previous fixes are correct, (2) whether fixes introduced new problems, (3) any remaining issues. Do not re-report issues that have already been fixed."
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Loop Exit Gatekeeper for prizmkit-code-review skill.
|
|
4
|
+
|
|
5
|
+
Stateless design: all loop state is passed via stdin and returned via stdout.
|
|
6
|
+
The caller (AI model) tracks `findings_history` and `max_rounds` between calls.
|
|
7
|
+
No runtime files are created — the script is a pure function over JSON.
|
|
8
|
+
|
|
9
|
+
The model supplies the current round in each call — the script does not auto-increment
|
|
10
|
+
rounds, because the gate is called twice per loop iteration (after Reviewer returns
|
|
11
|
+
and after Main Agent filters), and only the model knows when a full cycle completes.
|
|
12
|
+
|
|
13
|
+
Usage:
|
|
14
|
+
echo '{"reviewer_result":"NEEDS_FIXES","accepted_count":2,"findings_count":5,"round":1,"findings_history":[],"max_rounds":3,"filtering_done":true}' | python3 check_loop.py
|
|
15
|
+
|
|
16
|
+
Input JSON schema:
|
|
17
|
+
{
|
|
18
|
+
"reviewer_result": "PASS" | "NEEDS_FIXES",
|
|
19
|
+
"accepted_count": int,
|
|
20
|
+
"findings_count": int,
|
|
21
|
+
"round": int,
|
|
22
|
+
"findings_history": [int, ...],
|
|
23
|
+
"max_rounds": int,
|
|
24
|
+
"filtering_done": bool
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
Output JSON schema:
|
|
28
|
+
{
|
|
29
|
+
"endLoop": bool,
|
|
30
|
+
"reason": str,
|
|
31
|
+
"verdict": "PASS" | "NEEDS_FIXES" | null,
|
|
32
|
+
"round": int,
|
|
33
|
+
"maxRounds": int,
|
|
34
|
+
"divergenceWarning": bool,
|
|
35
|
+
"findings_history": [int, ...]
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
Exit conditions (checked in order):
|
|
39
|
+
1. Reviewer returned PASS → endLoop=true, verdict=PASS
|
|
40
|
+
2. NEEDS_FIXES before filtering → endLoop=false, wait for filtering
|
|
41
|
+
3. Filtered findings all rejected → endLoop=true, verdict=PASS
|
|
42
|
+
4. Max rounds reached after filtering → endLoop=true, verdict=NEEDS_FIXES
|
|
43
|
+
5. Otherwise → endLoop=false
|
|
44
|
+
|
|
45
|
+
Divergence detection:
|
|
46
|
+
If findings_count strictly increases for 3 consecutive rounds, set divergenceWarning=true.
|
|
47
|
+
This is a warning only — it does not force loop exit.
|
|
48
|
+
"""
|
|
49
|
+
|
|
50
|
+
import json
|
|
51
|
+
import sys
|
|
52
|
+
|
|
53
|
+
DEFAULT_MAX_ROUNDS = 3
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def check_divergence(findings_history):
|
|
57
|
+
"""Return True if the last 3 entries in findings_history are strictly increasing."""
|
|
58
|
+
if len(findings_history) < 3:
|
|
59
|
+
return False
|
|
60
|
+
last_three = findings_history[-3:]
|
|
61
|
+
return last_three[0] < last_three[1] < last_three[2]
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def record_findings_count(findings_history, current_round, findings_count):
|
|
65
|
+
"""Record findings_count once per round index, updating duplicate calls for the same round."""
|
|
66
|
+
if current_round <= 0:
|
|
67
|
+
return findings_history
|
|
68
|
+
|
|
69
|
+
target_index = current_round - 1
|
|
70
|
+
while len(findings_history) < target_index:
|
|
71
|
+
findings_history.append(0)
|
|
72
|
+
|
|
73
|
+
if len(findings_history) == target_index:
|
|
74
|
+
findings_history.append(findings_count)
|
|
75
|
+
else:
|
|
76
|
+
findings_history[target_index] = findings_count
|
|
77
|
+
|
|
78
|
+
return findings_history
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def check_exit_condition(data):
|
|
82
|
+
"""Determine whether the loop should exit. Pure function — no side effects.
|
|
83
|
+
|
|
84
|
+
Round is model-supplied — the script does not auto-increment it because
|
|
85
|
+
the gate is called twice per loop iteration (after Step 2 and Step 3).
|
|
86
|
+
"""
|
|
87
|
+
reviewer_result = data.get("reviewer_result")
|
|
88
|
+
accepted_count = data.get("accepted_count", 0)
|
|
89
|
+
findings_count = data.get("findings_count", 0)
|
|
90
|
+
current_round = data.get("round", 0)
|
|
91
|
+
findings_history = list(data.get("findings_history", []))
|
|
92
|
+
max_rounds = data.get("max_rounds", DEFAULT_MAX_ROUNDS)
|
|
93
|
+
filtering_done = data.get("filtering_done", reviewer_result == "PASS")
|
|
94
|
+
|
|
95
|
+
findings_history = record_findings_count(
|
|
96
|
+
findings_history, current_round, findings_count
|
|
97
|
+
)
|
|
98
|
+
divergence_warning = check_divergence(findings_history)
|
|
99
|
+
|
|
100
|
+
# Condition 1: Reviewer returned PASS
|
|
101
|
+
if reviewer_result == "PASS":
|
|
102
|
+
return {
|
|
103
|
+
"endLoop": True,
|
|
104
|
+
"reason": f"Round {current_round}: Reviewer returned PASS",
|
|
105
|
+
"verdict": "PASS",
|
|
106
|
+
"round": current_round,
|
|
107
|
+
"maxRounds": max_rounds,
|
|
108
|
+
"divergenceWarning": False,
|
|
109
|
+
"findings_history": findings_history,
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
# Condition 2: Reviewer returned findings, but filtering has not happened yet
|
|
113
|
+
if reviewer_result == "NEEDS_FIXES" and not filtering_done:
|
|
114
|
+
return {
|
|
115
|
+
"endLoop": False,
|
|
116
|
+
"reason": f"Round {current_round}: reviewer returned findings; filter before applying exit conditions",
|
|
117
|
+
"verdict": None,
|
|
118
|
+
"round": current_round,
|
|
119
|
+
"maxRounds": max_rounds,
|
|
120
|
+
"divergenceWarning": divergence_warning,
|
|
121
|
+
"findings_history": findings_history,
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
# Condition 3: All findings rejected after filtering
|
|
125
|
+
if reviewer_result == "NEEDS_FIXES" and accepted_count == 0:
|
|
126
|
+
return {
|
|
127
|
+
"endLoop": True,
|
|
128
|
+
"reason": f"Round {current_round}: all findings rejected by main agent",
|
|
129
|
+
"verdict": "PASS",
|
|
130
|
+
"round": current_round,
|
|
131
|
+
"maxRounds": max_rounds,
|
|
132
|
+
"divergenceWarning": False,
|
|
133
|
+
"findings_history": findings_history,
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
# Condition 4: Max rounds reached
|
|
137
|
+
if current_round >= max_rounds:
|
|
138
|
+
return {
|
|
139
|
+
"endLoop": True,
|
|
140
|
+
"reason": f"Hard limit: max {max_rounds} rounds reached",
|
|
141
|
+
"verdict": "NEEDS_FIXES",
|
|
142
|
+
"round": current_round,
|
|
143
|
+
"maxRounds": max_rounds,
|
|
144
|
+
"divergenceWarning": divergence_warning,
|
|
145
|
+
"findings_history": findings_history,
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
# Condition 5: Continue loop
|
|
149
|
+
next_round = current_round + 1
|
|
150
|
+
return {
|
|
151
|
+
"endLoop": False,
|
|
152
|
+
"reason": f"Round {current_round}: {accepted_count} findings accepted, continuing to round {next_round}",
|
|
153
|
+
"verdict": None,
|
|
154
|
+
"round": current_round,
|
|
155
|
+
"maxRounds": max_rounds,
|
|
156
|
+
"divergenceWarning": divergence_warning,
|
|
157
|
+
"findings_history": findings_history,
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
def main():
|
|
162
|
+
# Read input from stdin
|
|
163
|
+
try:
|
|
164
|
+
data = json.load(sys.stdin)
|
|
165
|
+
except json.JSONDecodeError as e:
|
|
166
|
+
print(
|
|
167
|
+
json.dumps(
|
|
168
|
+
{
|
|
169
|
+
"endLoop": False,
|
|
170
|
+
"reason": f"Invalid JSON input: {e}",
|
|
171
|
+
"verdict": None,
|
|
172
|
+
"round": 0,
|
|
173
|
+
"maxRounds": DEFAULT_MAX_ROUNDS,
|
|
174
|
+
"divergenceWarning": False,
|
|
175
|
+
"findings_history": [],
|
|
176
|
+
}
|
|
177
|
+
)
|
|
178
|
+
)
|
|
179
|
+
sys.exit(1)
|
|
180
|
+
|
|
181
|
+
result = check_exit_condition(data)
|
|
182
|
+
print(json.dumps(result))
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
if __name__ == "__main__":
|
|
186
|
+
main()
|
|
@@ -10,6 +10,12 @@ description: "Pure git commit workflow with safety checks. Stages files, generat
|
|
|
10
10
|
- After `/prizmkit-retrospective` has finished architecture sync
|
|
11
11
|
- The UserPromptSubmit hook will remind to use this skill when commit intent is detected
|
|
12
12
|
|
|
13
|
+
### When NOT to Use
|
|
14
|
+
- No uncommitted changes exist — nothing to commit
|
|
15
|
+
- .prizmkit/prizm-docs/ not synced — run /prizmkit-retrospective first
|
|
16
|
+
- Code review not passed in pipeline mode — run /prizmkit-code-review first
|
|
17
|
+
- Mid-merge conflict resolution — handle manually with git
|
|
18
|
+
|
|
13
19
|
**PRECONDITION:**
|
|
14
20
|
|
|
15
21
|
| Required State | Check | If Missing |
|
|
@@ -14,6 +14,51 @@ Three possible outcomes depending on what's supported:
|
|
|
14
14
|
|
|
15
15
|
When invited, behave as a deployment engineer. Ask until you understand what is being deployed, where it runs, how it is built, how it starts, what secrets it needs, how traffic reaches it, and how health is checked.
|
|
16
16
|
|
|
17
|
+
### When to Use
|
|
18
|
+
- User says "deploy", "ship it", "take this live", "deploy to Vercel", "deploy to my server"
|
|
19
|
+
- User wants to check deploy status, view logs, restart app, rollback
|
|
20
|
+
- First-time deployment configuration or repair
|
|
21
|
+
- Any deployment, hosting, or server operation question
|
|
22
|
+
|
|
23
|
+
### When NOT to Use
|
|
24
|
+
- Project has no code to deploy (empty/scaffold project)
|
|
25
|
+
- Local dev environment startup — use the project's dev scripts instead
|
|
26
|
+
- Purely CI/CD pipeline debugging unrelated to deployment
|
|
27
|
+
- User wants to edit application code — use /prizmkit-plan and /prizmkit-implement
|
|
28
|
+
|
|
29
|
+
## Data Safety Gate
|
|
30
|
+
|
|
31
|
+
Before executing any command that could **irreversibly destroy, overwrite, or modify data**, pause and get explicit user confirmation. This is a hard gate — the cost of a false negative (losing real data) is catastrophic, while asking one extra question costs nothing.
|
|
32
|
+
|
|
33
|
+
### Detection
|
|
34
|
+
|
|
35
|
+
Before running any shell command, scan it for these patterns:
|
|
36
|
+
|
|
37
|
+
| Category | Dangerous patterns | What's at risk |
|
|
38
|
+
|----------|-------------------|----------------|
|
|
39
|
+
| Database schema | `prisma db push --force-reset`, `prisma db push --accept-data-loss`, `prisma migrate reset`, `prisma migrate dev --create-only` | All existing data dropped, schema reset |
|
|
40
|
+
| Database data | `DROP TABLE`, `DROP DATABASE`, `TRUNCATE`, `DELETE FROM` without `WHERE`, `UPDATE` without `WHERE` | Data deletion or corruption |
|
|
41
|
+
| File system | `rm -rf`, `> /etc/`, overwriting existing configs without backup | Config loss, system breakage |
|
|
42
|
+
| Cloud resources | `terraform destroy`, `kubectl delete`, cloud resource deletion, S3 bucket removal | Infrastructure/service loss |
|
|
43
|
+
|
|
44
|
+
### Confirmation Flow
|
|
45
|
+
|
|
46
|
+
When a dangerous pattern is detected:
|
|
47
|
+
|
|
48
|
+
1. **Stop.** Do not execute. Do not ask "should I proceed?" while already running the command.
|
|
49
|
+
2. **Explain** what the command will do and what data will be lost, in plain language.
|
|
50
|
+
3. **Ask** an explicit yes/no question. Accept only a clear "yes" or equivalent — ambiguous responses ("sure, I guess", "ok go ahead") count as "no" when the consequence is data loss.
|
|
51
|
+
4. **Only proceed** on unambiguous consent. If the user says anything other than a clear affirmative, abort.
|
|
52
|
+
5. **Record** the confirmation decision and the command that was run in deploy history.
|
|
53
|
+
|
|
54
|
+
### Headless Mode
|
|
55
|
+
|
|
56
|
+
If a destructive data operation is detected in headless mode, **refuse and exit** with `DATA_SAFETY_DENIED`. Data destruction must never happen without human oversight — an unattended pipeline that runs `--force-reset` could wipe a production database with no one watching.
|
|
57
|
+
|
|
58
|
+
### Examples
|
|
59
|
+
|
|
60
|
+
Read `${SKILL_DIR}/references/data-safety-examples.md` for concrete few-shot examples of dangerous commands caught by this gate, including the correct and incorrect ways to handle them.
|
|
61
|
+
|
|
17
62
|
## Deployment Discovery
|
|
18
63
|
|
|
19
64
|
Before doing anything else, discover what you're deploying and where. This phase routes the request to the right adapter or fallback. It runs regardless of mode (interactive or headless), but interactive mode may ask questions; headless mode reads from existing config and exits with `NEEDS_INPUT` if critical details are missing.
|
|
@@ -245,39 +290,7 @@ Write `deploy.config.json` with all collected values and `validated: {}` stubs f
|
|
|
245
290
|
|
|
246
291
|
Before first deployment, bootstrap the server. Present a plan showing every privileged action before executing anything.
|
|
247
292
|
|
|
248
|
-
|
|
249
|
-
```
|
|
250
|
-
locale-gen en_US.UTF-8 # fix locale warnings on bare Ubuntu
|
|
251
|
-
apt-get update -qq # refresh package list
|
|
252
|
-
```
|
|
253
|
-
|
|
254
|
-
**Check-and-install (idempotent):** Node.js, npm, PM2, Nginx, Git. Use v22 LTS if v25 not available.
|
|
255
|
-
|
|
256
|
-
**Detect port conflicts:** `ss -tlnp | grep :80 || true`. If port 80/443 is occupied, report and ask how to resolve.
|
|
257
|
-
|
|
258
|
-
**User and directory setup:**
|
|
259
|
-
```
|
|
260
|
-
useradd -m -s /bin/bash <runtimeUser> # if not exists
|
|
261
|
-
mkdir -p /var/www/<project>/{releases,shared,deploy-logs}
|
|
262
|
-
chown -R <runtimeUser>:<runtimeUser> /var/www/<project>
|
|
263
|
-
```
|
|
264
|
-
|
|
265
|
-
**PM2 startup:**
|
|
266
|
-
```
|
|
267
|
-
env PATH=$PATH:/usr/bin pm2 startup systemd -u <runtimeUser> --hp /home/<runtimeUser>
|
|
268
|
-
```
|
|
269
|
-
|
|
270
|
-
**Deploy key (Pull mode only):**
|
|
271
|
-
```
|
|
272
|
-
sudo -u <runtimeUser> ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519 -N ""
|
|
273
|
-
sudo -u <runtimeUser> ssh-keyscan -H github.com >> ~/.ssh/known_hosts
|
|
274
|
-
```
|
|
275
|
-
|
|
276
|
-
**Security baseline (firewall):** After core tools are installed, ask whether to configure ufw. If user agrees, read `references/firewall-setup.md` for the full interactive flow and rule templates.
|
|
277
|
-
|
|
278
|
-
**Database setup:** If Discovery detected database drivers, ask whether to install the database on the server. If user agrees, read `references/database-setup.md` for platform-specific setup commands and security notes.
|
|
279
|
-
|
|
280
|
-
After each bootstrap step, record the result. Bootstrap operations must be idempotent. Back up any existing config files before modifying them.
|
|
293
|
+
Read `${SKILL_DIR}/references/ssh-bootstrap-flow.md` for the full bootstrap procedure (preflight, check-and-install, user/dir setup, PM2 startup, deploy key). When the bootstrap reaches firewall or database steps, it routes to `references/firewall-setup.md` and `references/database-setup.md`. Key rules: bootstrap operations must be idempotent, existing config files must be backed up before modification, and each step's result must be recorded.
|
|
281
294
|
|
|
282
295
|
### SSH: Direct Upload Deployment
|
|
283
296
|
|
|
@@ -294,7 +307,7 @@ After generating the workflow, verify: the first `git push` to the configured br
|
|
|
294
307
|
Before SSL, check if the user has a domain pointing to the server.
|
|
295
308
|
|
|
296
309
|
1. Ask: "你有没有域名要绑定到这个项目?" If no domain → skip DNS + SSL, note in deploy.md.
|
|
297
|
-
2. Check DNS:
|
|
310
|
+
2. Check DNS: `dig +short <domain> A`. If resolved → proceed to SSL.
|
|
298
311
|
3. If not resolved: show the user DNS setup instructions. Full procedure in `references/dns-setup.md`.
|
|
299
312
|
|
|
300
313
|
### SSH: SSL/HTTPS Configuration
|
|
@@ -310,37 +323,7 @@ Full procedure in `references/ssl-setup.md`.
|
|
|
310
323
|
|
|
311
324
|
### SSH: Deployment Execution Flow
|
|
312
325
|
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
**Pre-flight — Change Summary:** Show what will be deployed using `git log --oneline <last-deployed-commit>..HEAD`. If first deployment, show last 5 commits. If no new commits, warn "没有新的代码变更。确定要重新部署吗?"
|
|
316
|
-
|
|
317
|
-
**Group 1 — Pre-flight & Prepare:**
|
|
318
|
-
- Verify SSH, runtime user, tools, deploy key, port availability.
|
|
319
|
-
- Generate `releaseId`: `YYYYMMDD-<short-commit-sha>`. Create `releases/<releaseId>`.
|
|
320
|
-
- Determine target color: read `activeColor` from `shared/deploy-metadata.json` and use the opposite. If first deploy (no metadata, no `current` symlink), default to blue (port 3101).
|
|
321
|
-
|
|
322
|
-
**Group 2 — Fetch & Build:**
|
|
323
|
-
|
|
324
|
-
- **CI/CD Pull mode** (server-side build): git clone → install → copy `.env.production` before build (NEXT_PUBLIC_* vars are baked at build time) → build. If build fails: STOP.
|
|
325
|
-
- **CI/CD Push mode** (runner-side build): extract tarball, skip install/build.
|
|
326
|
-
- **Direct-upload mode**: build was already done locally and SCP'd. Skip this group.
|
|
327
|
-
|
|
328
|
-
**Group 3 — Stage & Health Check:**
|
|
329
|
-
- Start new version on inactive port via PM2: `pm2 start npm --name <project>-<app>-<color> -- run start -- -p <inactivePort>`.
|
|
330
|
-
- PM2 process naming: `<project>-<app>-<color>` (e.g., `prizm-ideas-web-green`).
|
|
331
|
-
- Wait 3-5 seconds, run health checks against new port. If any fails: STOP, do NOT switch traffic.
|
|
332
|
-
|
|
333
|
-
**Group 4 — Switch & Verify:**
|
|
334
|
-
- Update Nginx upstream to new port. Run `nginx -t` — abort on failure.
|
|
335
|
-
- `systemctl reload nginx`. Update `current` symlink to new release.
|
|
336
|
-
- Write `shared/deploy-metadata.json` with new `activeColor`, `activePort`, `lastReleaseId`.
|
|
337
|
-
- Run health checks against public endpoint. If any fails: rollback immediately.
|
|
338
|
-
|
|
339
|
-
**Group 5 — Cleanup & Record:**
|
|
340
|
-
- Stop old PM2 process. Remove oldest releases beyond `releaseRetention` count. `pm2 save`.
|
|
341
|
-
- Write deploy-history JSON. Update `deploy.config.json` validation status.
|
|
342
|
-
|
|
343
|
-
**Post-deploy — Completion Summary:** Output a summary (project, URL, version, duration, health status) and append to deploy.md. If `deployStrategy` is `"direct-upload"`, offer CI/CD upgrade (see §SSH: Post-Deploy CI/CD Upgrade).
|
|
326
|
+
Read `${SKILL_DIR}/references/ssh-execution-flow.md` for the full 5-group pipeline: pre-flight, fetch & build, stage & health check, switch & verify, cleanup & record. Key invariant: if any step before traffic switch fails, STOP — do not touch the live version.
|
|
344
327
|
|
|
345
328
|
### SSH: Blue/Green PM2 + Nginx Strategy
|
|
346
329
|
|
|
@@ -405,14 +388,7 @@ Deploy history records secret presence metadata only (e.g., `{"SUPABASE_SERVICE_
|
|
|
405
388
|
|
|
406
389
|
### SSH: Existing Deployment Takeover
|
|
407
390
|
|
|
408
|
-
When deploying to a server that already has deployment assets
|
|
409
|
-
|
|
410
|
-
1. Detect: existing `/var/www/<project>` directory, existing PM2 processes with similar names, Nginx config referencing the same domain/IP, port conflicts.
|
|
411
|
-
2. Report findings and ask for takeover decision:
|
|
412
|
-
- **Take over and backup**: Back up existing config, then proceed.
|
|
413
|
-
- **Coexist**: Use different directory/ports/process names.
|
|
414
|
-
- **Manual resolve**: Stop and let the user handle it.
|
|
415
|
-
3. Record takeover decision and validation results in config and history.
|
|
391
|
+
When deploying to a server that already has deployment assets, read `${SKILL_DIR}/references/ssh-takeover.md` for the detection procedure and takeover decision flow. Record takeover decision and validation results in config and history.
|
|
416
392
|
|
|
417
393
|
### SSH: Nginx Management
|
|
418
394
|
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
# Data Safety Examples
|
|
2
|
+
|
|
3
|
+
Few-shot examples for the Data Safety Gate in `/prizmkit-deploy`. Read this file when a dangerous command pattern is detected — it shows the correct confirmation flow and illustrates what happens when the gate is skipped.
|
|
4
|
+
|
|
5
|
+
## Example 1: Prisma Force Reset (the incident)
|
|
6
|
+
|
|
7
|
+
**Context:** User runs `/prizmkit-deploy` to deploy a Next.js + Prisma project. During database setup, the model needs to sync the Prisma schema with the database.
|
|
8
|
+
|
|
9
|
+
**Wrong — skipping the gate:**
|
|
10
|
+
```
|
|
11
|
+
Model: I'll sync your database schema now.
|
|
12
|
+
$ prisma db push --force-reset --accept-schema
|
|
13
|
+
→ All tables dropped. All production data lost. No backup. No confirmation.
|
|
14
|
+
```
|
|
15
|
+
This happened in production. `--force-reset` drops and recreates every table. `--accept-schema` bypasses Prisma's own confirmation prompt. The model ran both flags without asking the user whether existing data should be preserved.
|
|
16
|
+
|
|
17
|
+
**Correct — with the safety gate:**
|
|
18
|
+
```
|
|
19
|
+
Model: I detected that your database needs a schema sync. However, before I do anything:
|
|
20
|
+
|
|
21
|
+
WARNING: The Prisma schema has changes that could affect existing data.
|
|
22
|
+
- New tables to create: 0
|
|
23
|
+
- Tables that may be modified: 2 (users, orders)
|
|
24
|
+
- If I run `prisma db push --force-reset`, ALL existing data will be DESTROYED.
|
|
25
|
+
|
|
26
|
+
Options:
|
|
27
|
+
1. prisma db push (safe — only adds missing tables/columns, no data loss)
|
|
28
|
+
2. prisma db push --force-reset (DANGEROUS — drops and recreates all tables, all data lost)
|
|
29
|
+
3. prisma migrate dev (creates a migration file you can review first)
|
|
30
|
+
|
|
31
|
+
Which approach do you want? (1/2/3)
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
The `--accept-schema` flag should never be used — it suppresses Prisma's own built-in safety prompts that protect the user.
|
|
35
|
+
|
|
36
|
+
## Example 2: Prisma Migrate Reset
|
|
37
|
+
|
|
38
|
+
**Context:** User wants to reset their dev database to a clean state for testing.
|
|
39
|
+
|
|
40
|
+
**Correct detection and confirmation:**
|
|
41
|
+
```
|
|
42
|
+
Model: `prisma migrate reset` will:
|
|
43
|
+
- Drop the entire database
|
|
44
|
+
- Recreate it from scratch
|
|
45
|
+
- Run all migrations
|
|
46
|
+
|
|
47
|
+
This is a DESTRUCTIVE operation. All data in the database will be permanently lost.
|
|
48
|
+
|
|
49
|
+
Are you sure this is a dev/test database with no important data? (yes/no)
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
In production or any environment with real data: refuse immediately. This command should only run in dev with explicit user confirmation.
|
|
53
|
+
|
|
54
|
+
## Example 3: Raw SQL Data Modification
|
|
55
|
+
|
|
56
|
+
**Context:** During deployment, the model considers running a SQL command to fix a data issue.
|
|
57
|
+
|
|
58
|
+
**Correct detection and confirmation:**
|
|
59
|
+
```
|
|
60
|
+
Model: To fix the duplicate user records, I would run:
|
|
61
|
+
```sql
|
|
62
|
+
DELETE FROM users WHERE email IS NULL AND created_at < '2025-01-01';
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
This would delete approximately 340 user records. BEFORE I run this:
|
|
66
|
+
|
|
67
|
+
1. Would you like me to run a SELECT first to show you exactly which rows would be deleted?
|
|
68
|
+
2. Do you want to back up the users table before deletion?
|
|
69
|
+
3. Confirm: Delete these 340 records? (yes/no)
|
|
70
|
+
|
|
71
|
+
I will not proceed without your explicit confirmation.
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Example 4: Overwriting Production Configuration
|
|
75
|
+
|
|
76
|
+
**Context:** During bootstrap, the model needs to write an Nginx config, but one already exists at the target path.
|
|
77
|
+
|
|
78
|
+
**Correct detection and confirmation:**
|
|
79
|
+
```
|
|
80
|
+
Model: Found existing Nginx config at /etc/nginx/sites-enabled/myapp.
|
|
81
|
+
|
|
82
|
+
This file is NOT managed by PrizmKit (no `# PrizmKit Managed:` marker).
|
|
83
|
+
Overwriting it could break existing site configuration.
|
|
84
|
+
|
|
85
|
+
Options:
|
|
86
|
+
1. Back up the existing config to /etc/nginx/sites-enabled/myapp.bak, then write new config
|
|
87
|
+
2. Create new config alongside existing one with a different name
|
|
88
|
+
3. Skip — keep the existing config as-is
|
|
89
|
+
|
|
90
|
+
Which approach? (1/2/3)
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## Example 5: Confirmation Dialogue Template
|
|
94
|
+
|
|
95
|
+
When the gate triggers, use this dialogue structure:
|
|
96
|
+
|
|
97
|
+
```
|
|
98
|
+
============================================================
|
|
99
|
+
DATA SAFETY GATE — DESTRUCTIVE OPERATION DETECTED
|
|
100
|
+
============================================================
|
|
101
|
+
|
|
102
|
+
Command: <the dangerous command>
|
|
103
|
+
Risk level: HIGH / CRITICAL
|
|
104
|
+
What will be lost: <plain-language description of affected data>
|
|
105
|
+
|
|
106
|
+
Current state:
|
|
107
|
+
- Database: <name>, <size>, <table count>
|
|
108
|
+
- Affected tables: <list>
|
|
109
|
+
- Last backup: <date if known, or "unknown — backup recommended">
|
|
110
|
+
|
|
111
|
+
Recommended safe approach:
|
|
112
|
+
<alternative if one exists>
|
|
113
|
+
|
|
114
|
+
Do you want to proceed with this destructive operation?
|
|
115
|
+
Type "yes, I understand the data will be lost" to confirm.
|
|
116
|
+
Any other response will abort.
|
|
117
|
+
============================================================
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
This format forces the user to read and acknowledge the risk before proceeding.
|
|
@@ -10,9 +10,9 @@ Read this file when `deployStrategy` is `"direct-upload"`. The AI handles the bu
|
|
|
10
10
|
|
|
11
11
|
## Transfer phase (SCP)
|
|
12
12
|
|
|
13
|
-
```
|
|
14
|
-
scp
|
|
15
|
-
ssh
|
|
13
|
+
```
|
|
14
|
+
scp -P <port> deploy-<releaseId>.tar.gz <runtimeUser>@<host>:/var/www/<project>/releases/
|
|
15
|
+
ssh <runtimeUser>@<host> "cd /var/www/<project>/releases && mkdir <releaseId> && tar xzf deploy-<releaseId>.tar.gz -C <releaseId>"
|
|
16
16
|
```
|
|
17
17
|
|
|
18
18
|
## Server-side setup
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# SSH Bootstrap Flow
|
|
2
|
+
|
|
3
|
+
Bootstraps the server before first deployment. Present a plan showing every privileged action before executing anything.
|
|
4
|
+
|
|
5
|
+
## Always-Run Preflight
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
locale-gen en_US.UTF-8 # fix locale warnings on bare Ubuntu
|
|
9
|
+
apt-get update -qq # refresh package list
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## Check-and-Install (idempotent)
|
|
13
|
+
|
|
14
|
+
Node.js, npm, PM2, Nginx, Git. Use v22 LTS if v25 not available.
|
|
15
|
+
|
|
16
|
+
## Detect Port Conflicts
|
|
17
|
+
|
|
18
|
+
`ss -tlnp | grep :80 || true`. If port 80/443 is occupied, report and ask how to resolve.
|
|
19
|
+
|
|
20
|
+
## User and Directory Setup
|
|
21
|
+
|
|
22
|
+
```
|
|
23
|
+
useradd -m -s /bin/bash <runtimeUser> # if not exists
|
|
24
|
+
mkdir -p /var/www/<project>/{releases,shared,deploy-logs}
|
|
25
|
+
chown -R <runtimeUser>:<runtimeUser> /var/www/<project>
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## PM2 Startup
|
|
29
|
+
|
|
30
|
+
```
|
|
31
|
+
env PATH=$PATH:/usr/bin pm2 startup systemd -u <runtimeUser> --hp /home/<runtimeUser>
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Deploy Key (Pull mode only)
|
|
35
|
+
|
|
36
|
+
```
|
|
37
|
+
sudo -u <runtimeUser> ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519 -N ""
|
|
38
|
+
sudo -u <runtimeUser> ssh-keyscan -H github.com >> ~/.ssh/known_hosts
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Security Baseline (Firewall)
|
|
42
|
+
|
|
43
|
+
After core tools are installed, ask whether to configure ufw. If user agrees, read `references/firewall-setup.md` for the full interactive flow and rule templates.
|
|
44
|
+
|
|
45
|
+
## Database Setup
|
|
46
|
+
|
|
47
|
+
If Discovery detected database drivers, ask whether to install the database on the server. If user agrees, read `references/database-setup.md` for platform-specific setup commands and security notes.
|
|
48
|
+
|
|
49
|
+
After each bootstrap step, record the result. Bootstrap operations must be idempotent. Back up any existing config files before modifying them.
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# SSH: Deployment Execution Flow
|
|
2
|
+
|
|
3
|
+
Pipeline runs in strict order. Each group must complete before the next begins. If any step before traffic switch fails, STOP — do not touch the live version.
|
|
4
|
+
|
|
5
|
+
## Pre-flight — Change Summary
|
|
6
|
+
|
|
7
|
+
Show what will be deployed using `git log --oneline <last-deployed-commit>..HEAD`. If first deployment, show last 5 commits. If no new commits, warn "没有新的代码变更。确定要重新部署吗?"
|
|
8
|
+
|
|
9
|
+
## Group 1 — Pre-flight & Prepare
|
|
10
|
+
|
|
11
|
+
- Verify SSH, runtime user, tools, deploy key, port availability.
|
|
12
|
+
- Generate `releaseId`: `YYYYMMDD-<short-commit-sha>`. Create `releases/<releaseId>`.
|
|
13
|
+
- Determine target color: read `activeColor` from `shared/deploy-metadata.json` and use the opposite. If first deploy (no metadata, no `current` symlink), default to blue (port 3101).
|
|
14
|
+
|
|
15
|
+
## Group 2 — Fetch & Build
|
|
16
|
+
|
|
17
|
+
- **CI/CD Pull mode** (server-side build): git clone → install → copy `.env.production` before build (NEXT_PUBLIC_* vars are baked at build time) → build. If build fails: STOP.
|
|
18
|
+
- **CI/CD Push mode** (runner-side build): extract tarball, skip install/build.
|
|
19
|
+
- **Direct-upload mode**: build was already done locally and SCP'd. Skip this group.
|
|
20
|
+
|
|
21
|
+
## Group 3 — Stage & Health Check
|
|
22
|
+
|
|
23
|
+
- Start new version on inactive port via PM2: `pm2 start npm --name <project>-<app>-<color> -- run start -- -p <inactivePort>`.
|
|
24
|
+
- PM2 process naming: `<project>-<app>-<color>` (e.g., `prizm-ideas-web-green`).
|
|
25
|
+
- Wait 3-5 seconds, run health checks against new port. If any fails: STOP, do NOT switch traffic.
|
|
26
|
+
|
|
27
|
+
## Group 4 — Switch & Verify
|
|
28
|
+
|
|
29
|
+
- Update Nginx upstream to new port. Run `nginx -t` — abort on failure.
|
|
30
|
+
- `systemctl reload nginx`. Update `current` symlink to new release.
|
|
31
|
+
- Write `shared/deploy-metadata.json` with new `activeColor`, `activePort`, `lastReleaseId`.
|
|
32
|
+
- Run health checks against public endpoint. If any fails: rollback immediately.
|
|
33
|
+
|
|
34
|
+
## Group 5 — Cleanup & Record
|
|
35
|
+
|
|
36
|
+
- Stop old PM2 process. Remove oldest releases beyond `releaseRetention` count. `pm2 save`.
|
|
37
|
+
- Write deploy-history JSON. Update `deploy.config.json` validation status.
|
|
38
|
+
|
|
39
|
+
## Post-deploy — Completion Summary
|
|
40
|
+
|
|
41
|
+
Output a summary (project, URL, version, duration, health status) and append to deploy.md. If `deployStrategy` is `"direct-upload"`, offer CI/CD upgrade (see §SSH: Post-Deploy CI/CD Upgrade).
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# SSH: Existing Deployment Takeover
|
|
2
|
+
|
|
3
|
+
When deploying to a server that already has deployment assets.
|
|
4
|
+
|
|
5
|
+
## Detection
|
|
6
|
+
|
|
7
|
+
1. Check for existing `/var/www/<project>` directory
|
|
8
|
+
2. Check for existing PM2 processes with similar names
|
|
9
|
+
3. Check Nginx config referencing the same domain/IP
|
|
10
|
+
4. Check for port conflicts
|
|
11
|
+
|
|
12
|
+
## Decision Flow
|
|
13
|
+
|
|
14
|
+
Report findings and ask for takeover decision:
|
|
15
|
+
|
|
16
|
+
- **Take over and backup**: Back up existing config, then proceed.
|
|
17
|
+
- **Coexist**: Use different directory/ports/process names.
|
|
18
|
+
- **Manual resolve**: Stop and let the user handle it.
|
|
19
|
+
|
|
20
|
+
Record takeover decision and validation results in config and history.
|