secufusion-mcp 2.1.6 → 2.2.0
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/README.md +5 -3
- package/agents/AGENTS.md +224 -31
- package/agents/reviewer.md +231 -304
- package/commands/sfn-code.md +72 -6
- package/commands/sfn-init.md +506 -36
- package/commands/sfn-review.md +695 -30
- package/mcp/dist/parsers/events.js +11 -4
- package/mcp/dist/server.js +253 -1396
- package/package.json +2 -2
- package/scripts/.secufusion-migrations.json +395 -0
- package/scripts/.secufusion-project-spec.json +857 -0
package/commands/sfn-code.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
---
|
|
2
2
|
description: Execute the approved implementation plan. Switches to the Coder Persona and writes code precisely as planned, using rejected-pattern memory to avoid past mistakes.
|
|
3
3
|
argument-hint: <ticket-id> e.g. WI-123
|
|
4
4
|
---
|
|
@@ -20,7 +20,19 @@ Task: **$ARGUMENTS**
|
|
|
20
20
|
|
|
21
21
|
Call `get_pattern_from_task(work_item_id: "$ARGUMENTS")` to retrieve any rejected patterns logged for this task. If patterns exist, internalize them as hard constraints — **do not repeat them under any circumstances.**
|
|
22
22
|
|
|
23
|
-
## Phase 2 —
|
|
23
|
+
## Phase 2 — Load Migration Context
|
|
24
|
+
|
|
25
|
+
**Before writing a single line of code**, read `.secufusion-migrations.json` from the workspace root (or `scripts/` subfolder).
|
|
26
|
+
|
|
27
|
+
From this file, load for each service involved in this task:
|
|
28
|
+
- `current_state.next_suggested` — the correct next migration filename
|
|
29
|
+
- `organization.version_gaps` — version numbers that MUST NOT be reused
|
|
30
|
+
- `mcp_guardrails.naming_pattern_to_enforce` — the regex all filenames must match
|
|
31
|
+
- `content_conventions.comment_style` — how to write the migration header block
|
|
32
|
+
|
|
33
|
+
If the file is not found: warn the user and continue, but flag any DB changes as requiring manual migration creation before deploy.
|
|
34
|
+
|
|
35
|
+
## Phase 3 — Implement
|
|
24
36
|
|
|
25
37
|
Execute the plan file step by step:
|
|
26
38
|
|
|
@@ -29,21 +41,75 @@ Execute the plan file step by step:
|
|
|
29
41
|
- On every new DB query: check for N+1 patterns and missing indexes. Flag before writing.
|
|
30
42
|
- On every Kafka publish: verify it is async / non-blocking. Flag synchronous calls.
|
|
31
43
|
|
|
32
|
-
|
|
44
|
+
### Migration awareness during implementation
|
|
45
|
+
|
|
46
|
+
After writing any of the following:
|
|
47
|
+
- New `@Entity` class
|
|
48
|
+
- New `@Column` on an existing entity
|
|
49
|
+
- Modified `@Column` (type, nullable, length change)
|
|
50
|
+
- Removed `@Column` or `@Table`
|
|
51
|
+
- New `@Table` or renamed table
|
|
52
|
+
|
|
53
|
+
**IMMEDIATELY stop and do the following:**
|
|
54
|
+
|
|
55
|
+
1. Read `.secufusion-migrations.json` (already loaded in Phase 2).
|
|
56
|
+
2. Identify which service this file belongs to from its path (e.g. `sfn-events-api/src/...`).
|
|
57
|
+
3. Look up `current_state.next_suggested` for that service.
|
|
58
|
+
4. Check `organization.version_gaps` — do NOT use any of those version numbers.
|
|
59
|
+
5. Warn the developer:
|
|
33
60
|
|
|
34
|
-
|
|
61
|
+
```
|
|
62
|
+
⚠️ DB CHANGE DETECTED
|
|
63
|
+
File: {entity file path}
|
|
64
|
+
Service: {inferred service name}
|
|
65
|
+
|
|
66
|
+
A migration script is required before this can be deployed.
|
|
67
|
+
|
|
68
|
+
Next migration for this service: {next_suggested from .secufusion-migrations.json}
|
|
69
|
+
Location: src/main/resources/db/migration/
|
|
70
|
+
|
|
71
|
+
🔴 IMPORTANT: SecuFusion applies migration scripts MANUALLY.
|
|
72
|
+
Nothing runs automatically on boot.
|
|
73
|
+
You MUST run the script against the target PostgreSQL database
|
|
74
|
+
BEFORE deploying this code.
|
|
75
|
+
|
|
76
|
+
Shall I draft the migration script now?
|
|
77
|
+
Reply YES and I will create a draft following:
|
|
78
|
+
- Naming: {naming_pattern_description from .secufusion-migrations.json}
|
|
79
|
+
- Comment header style: {comment_style from content_conventions}
|
|
80
|
+
- IF NOT EXISTS guards where applicable
|
|
81
|
+
- Index in same file for any new filterable column
|
|
82
|
+
- Constraint naming: {constraint_naming from content_conventions}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
**If the developer says YES:**
|
|
86
|
+
- Draft the migration SQL.
|
|
87
|
+
- Show the draft for review — do NOT write the file until the developer approves.
|
|
88
|
+
- After approval, log the new file with `manage_task(action: "log_file_touched")`.
|
|
89
|
+
|
|
90
|
+
After each logical step, call `manage_task(action: "update_spec", work_item_id: "$ARGUMENTS", next_step: "<what was just completed>")` to track progress.
|
|
91
|
+
|
|
92
|
+
## Phase 4 — Self-Review
|
|
35
93
|
|
|
36
94
|
Before handing off, perform a fast self-review against the Acceptance Criteria in `plan.md`. For each criterion, confirm it is met with a `file:line` citation.
|
|
37
95
|
|
|
96
|
+
For every migration script created in this task, verify:
|
|
97
|
+
- [ ] Filename matches the naming pattern from `.secufusion-migrations.json`
|
|
98
|
+
- [ ] Version number is the correct next (not a gap, not already used)
|
|
99
|
+
- [ ] File has a comment header with WHY context
|
|
100
|
+
- [ ] IF NOT EXISTS guards used for CREATE TABLE
|
|
101
|
+
- [ ] Indexes included in same file for new filterable columns
|
|
102
|
+
|
|
38
103
|
If any criterion is unmet, fix it now before reporting.
|
|
39
104
|
|
|
40
|
-
## Phase
|
|
105
|
+
## Phase 5 — Handoff
|
|
41
106
|
|
|
42
107
|
Call `manage_task(action: "complete", work_item_id: "$ARGUMENTS")` to mark the task as coded.
|
|
43
108
|
|
|
44
109
|
Report to the user:
|
|
45
110
|
- Files created/modified
|
|
46
111
|
- ACs met (with file:line)
|
|
112
|
+
- Migration scripts created (with manual run reminder)
|
|
47
113
|
- Any open risks or deferred items
|
|
48
114
|
|
|
49
|
-
> 🚀 Implementation complete. Run `/sfn-review` to run the zero-tolerance PR gate checks.
|
|
115
|
+
> 🚀 Implementation complete. Run `/sfn-review $ARGUMENTS` to run the zero-tolerance PR gate checks.
|
package/commands/sfn-init.md
CHANGED
|
@@ -1,57 +1,527 @@
|
|
|
1
1
|
---
|
|
2
|
-
description:
|
|
3
|
-
argument-hint: (no args) — run from the root
|
|
2
|
+
description: "Bootstrap the SecuFusion workspace. Generates .secufusion-project-spec.json and .secufusion-migrations.json on first run. On re-run, performs a version-aware merge — updates MCP-owned rules and terminology while preserving workspace-discovered data. Safe to run at any time."
|
|
3
|
+
argument-hint: "(no args) — run from the repo root. Safe to re-run after MCP updates."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
You are executing the **sfn-init** bootstrap command
|
|
6
|
+
You are executing the **sfn-init** bootstrap command.
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
This command is safe to re-run at any time. It never blindly overwrites.
|
|
9
|
+
On re-run it detects what changed and merges intelligently.
|
|
9
10
|
|
|
10
|
-
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## STEP 0 — Check what already exists and whether it is current
|
|
14
|
+
|
|
15
|
+
### 0.1 — Locate all three files
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
.secufusion-project-spec.json
|
|
19
|
+
→ Check workspace root first
|
|
20
|
+
→ Check up to 3 parent directories
|
|
21
|
+
→ Check same directory as the MCP server binary
|
|
22
|
+
|
|
23
|
+
.secufusion-migrations.json
|
|
24
|
+
→ Check workspace root
|
|
25
|
+
→ Check scripts/ subfolder
|
|
26
|
+
|
|
27
|
+
.secufusion/dna.json
|
|
28
|
+
→ Check .secufusion/ in workspace root
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### 0.2 — For .secufusion-project-spec.json: version check
|
|
32
|
+
|
|
33
|
+
If the file exists, read its `_meta.mcp_spec_version` field.
|
|
34
|
+
|
|
35
|
+
**Read the currently installed MCP version** from the `package.json` of the
|
|
36
|
+
`secufusion-mcp` npm package. Locate it using this priority:
|
|
37
|
+
|
|
38
|
+
```
|
|
39
|
+
1. package.json in the same directory as the MCP server binary (most reliable)
|
|
40
|
+
2. npm list -g secufusion-mcp → parse the version from output (e.g. "secufusion-mcp@2.1.9")
|
|
41
|
+
3. The "version" field in the nearest package.json walking up from server binary location
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
This installed version IS the MCP canonical version. It changes automatically when the
|
|
45
|
+
developer publishes a new npm version (`npm publish`). No manual version tracking required.
|
|
46
|
+
|
|
47
|
+
**Version decision table:**
|
|
48
|
+
|
|
49
|
+
| Workspace file exists? | `mcp_spec_version` matches? | Action |
|
|
50
|
+
|---|---|---|
|
|
51
|
+
| NO | — | Fresh install → generate from scratch (Phase 1 + 2) |
|
|
52
|
+
| YES | YES (up to date) | No changes needed → skip Phase 2, load and report |
|
|
53
|
+
| YES | NO (stale) | Merge required → run Phase 1 scan + Phase 2 MERGE |
|
|
54
|
+
| YES | field missing (very old) | Treat as stale → run merge |
|
|
55
|
+
|
|
56
|
+
### 0.3 — For .secufusion-migrations.json
|
|
57
|
+
|
|
58
|
+
If exists: check if any new `.sql` files exist in migration folders that are NOT
|
|
59
|
+
recorded in this file → if yes, trigger migration refresh in Phase 3.
|
|
60
|
+
If not exists: generate it.
|
|
61
|
+
|
|
62
|
+
### 0.4 — For .secufusion/dna.json
|
|
63
|
+
|
|
64
|
+
If exists and `scannedAt` is less than 7 days ago: use existing, skip Phase 4 scan.
|
|
65
|
+
If exists and older than 7 days: offer refresh — ask user: "DNA is X days old. Refresh? (Y/n)"
|
|
66
|
+
If not exists: generate it.
|
|
67
|
+
|
|
68
|
+
### 0.5 — Report what will happen
|
|
69
|
+
|
|
70
|
+
Before doing any work, tell the user:
|
|
71
|
+
|
|
72
|
+
```
|
|
73
|
+
📋 Init plan for this workspace:
|
|
74
|
+
|
|
75
|
+
.secufusion-project-spec.json → {FRESH INSTALL | UP TO DATE | MERGE REQUIRED (v{old} → v{new})}
|
|
76
|
+
.secufusion-migrations.json → {GENERATE | UP TO DATE | REFRESH (new SQL files detected)}
|
|
77
|
+
.secufusion/dna.json → {GENERATE | UP TO DATE | REFRESH OFFERED (X days old)}
|
|
78
|
+
|
|
79
|
+
Proceeding...
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Do not ask for confirmation before proceeding — just report the plan and execute.
|
|
83
|
+
The user can interrupt if they disagree.
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
## PHASE 1 — Scan the repository (runs on fresh install OR merge)
|
|
11
88
|
|
|
12
|
-
|
|
89
|
+
Run all 4 tools **concurrently in a single message**:
|
|
13
90
|
|
|
14
|
-
1. `scan_repository_stack`
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
4. `extract_event_topics` — map all Kafka/event-bus topics, producers, and consumers.
|
|
91
|
+
1. `scan_repository_stack(workspace_root: <workspace_root>)`
|
|
92
|
+
→ Identifies language, framework, package manager, services, build/test commands
|
|
93
|
+
→ Detects if this is a monorepo
|
|
18
94
|
|
|
19
|
-
|
|
95
|
+
2. `extract_domain_models(workspace_root: <workspace_root>)`
|
|
96
|
+
→ Maps all domain entities, their fields, and relationships
|
|
97
|
+
→ Identifies @Entity classes, their columns, and inter-entity relationships
|
|
98
|
+
→ Note: "Device" in older code may mean a Browser install, not a physical machine
|
|
20
99
|
|
|
21
|
-
|
|
100
|
+
3. `extract_api_endpoints(workspace_root: <workspace_root>)`
|
|
101
|
+
→ Maps all REST endpoints, HTTP methods, and owning services
|
|
102
|
+
→ Identifies gateway routes vs direct service-to-service calls
|
|
103
|
+
|
|
104
|
+
4. `extract_event_topics(workspace_root: <workspace_root>)`
|
|
105
|
+
→ Maps all Kafka topics, producers, and consumers per service
|
|
106
|
+
→ Flag any topics with no confirmed consumer (dead topic risk)
|
|
107
|
+
|
|
108
|
+
**While scans run, note:**
|
|
109
|
+
- Which services have a `src/main/resources/db/migration/` folder → these have manual migrations
|
|
110
|
+
- Which services have NO migration folder → these are schema-free
|
|
111
|
+
- Any service making direct REST calls that bypass the gateway
|
|
112
|
+
- Any Kafka topics with producers but no consumers (dead topics)
|
|
113
|
+
- Any inconsistency between "Device" and "Machine" naming in entity classes
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
## PHASE 2 — Generate or merge the spec file
|
|
118
|
+
|
|
119
|
+
After scans complete, write or update `.secufusion-project-spec.json` at the workspace root.
|
|
120
|
+
|
|
121
|
+
This file is the **permanent memory of the project**. Every MCP tool reads it.
|
|
122
|
+
|
|
123
|
+
### If FRESH INSTALL (file did not exist)
|
|
124
|
+
|
|
125
|
+
Generate from scratch using the structure below. Proceed to Required structure.
|
|
126
|
+
|
|
127
|
+
### If MERGE REQUIRED (file exists but is stale)
|
|
128
|
+
|
|
129
|
+
The spec has two kinds of sections with different owners:
|
|
130
|
+
|
|
131
|
+
```
|
|
132
|
+
MCP-OWNED sections (always updated from MCP defaults when stale):
|
|
133
|
+
_meta — version, timestamps, warnings
|
|
134
|
+
terminology — Device vs Machine rules (you defined these)
|
|
135
|
+
golden_rules — the non-negotiable rules (you defined these)
|
|
136
|
+
coding_style — naming conventions (you defined these)
|
|
137
|
+
platform — auth provider, event bus, migration strategy
|
|
138
|
+
|
|
139
|
+
WORKSPACE-OWNED sections (preserved from scan, updated with new scan results):
|
|
140
|
+
microservices — discovered from actual source code
|
|
141
|
+
kafka_topics — discovered from actual @KafkaListener / @KafkaProducer
|
|
142
|
+
cross_service_call_graph — discovered from actual RestTemplate / WebClient calls
|
|
143
|
+
services_with_migrations — discovered from actual migration folders
|
|
144
|
+
services_without_migrations — discovered from actual source structure
|
|
145
|
+
frontend — discovered from package.json / framework detection
|
|
146
|
+
chrome_extension — discovered from actual source
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
**Merge procedure (in order):**
|
|
150
|
+
|
|
151
|
+
1. **Backup first**
|
|
152
|
+
Copy existing file to `.secufusion-project-spec.json.backup-{YYYYMMDD-HHMMSS}`
|
|
153
|
+
Never lose the old state. Confirm backup written.
|
|
154
|
+
|
|
155
|
+
2. **Preserve workspace-owned data**
|
|
156
|
+
Read all WORKSPACE-OWNED sections from the existing file.
|
|
157
|
+
Hold them in memory — they will survive the merge.
|
|
158
|
+
|
|
159
|
+
3. **Re-scan workspace-owned sections**
|
|
160
|
+
Run Phase 1 scans to refresh: microservices, kafka_topics, call graph, migration lists.
|
|
161
|
+
Merge scan results with preserved data:
|
|
162
|
+
- If a service exists in both: keep existing config, update `kafka_produces` / `kafka_consumes` from scan
|
|
163
|
+
- If a service is new in scan: add it
|
|
164
|
+
- If a service was in old file but scan found it no longer exists: flag it with `"status": "NOT_FOUND_IN_LAST_SCAN"` — do NOT silently delete it
|
|
165
|
+
|
|
166
|
+
4. **Overwrite MCP-owned sections**
|
|
167
|
+
Replace `_meta`, `terminology`, `golden_rules`, `coding_style`, `platform` entirely
|
|
168
|
+
with the current MCP defaults. These are the sections you update when you push
|
|
169
|
+
a new version of the MCP. They propagate to every coworker on next init.
|
|
170
|
+
|
|
171
|
+
5. **Update `_meta.mcp_spec_version` and append to `_changelog`**
|
|
172
|
+
|
|
173
|
+
Read the installed npm version from `package.json` — this is the new `mcp_spec_version`.
|
|
174
|
+
Set `_meta.mcp_spec_version` to this value.
|
|
175
|
+
Set `_meta.generated_at` to now (ISO timestamp).
|
|
176
|
+
|
|
177
|
+
Then **append a new entry** to the `_changelog` array in the spec file.
|
|
178
|
+
The `mcp_spec_version` in this entry is the npm package version that ran init:
|
|
22
179
|
|
|
23
|
-
1. Write the combined findings to `.secufusion/dna.json` in the project root. Structure it as:
|
|
24
180
|
```json
|
|
25
181
|
{
|
|
26
|
-
"
|
|
27
|
-
"
|
|
28
|
-
"
|
|
29
|
-
"
|
|
30
|
-
"
|
|
31
|
-
"
|
|
182
|
+
"mcp_spec_version": "{npm package version — e.g. 2.2.0}",
|
|
183
|
+
"date": "{YYYY-MM-DD}",
|
|
184
|
+
"author": "sfn-init auto-merge",
|
|
185
|
+
"summary": "Spec merged: secufusion-mcp@{old_version} → secufusion-mcp@{new_version}",
|
|
186
|
+
"sections_changed": ["{MCP-owned sections overwritten}"],
|
|
187
|
+
"added": [
|
|
188
|
+
"{new golden rule id}: {what it enforces}",
|
|
189
|
+
"{new terminology key}: {what it means}"
|
|
190
|
+
],
|
|
191
|
+
"modified": [
|
|
192
|
+
"{rule id}: {what changed — e.g. severity WARNING → BLOCKER}"
|
|
193
|
+
],
|
|
194
|
+
"removed": [
|
|
195
|
+
"{anything removed from golden_rules or terminology}"
|
|
196
|
+
],
|
|
197
|
+
"workspace_changes": [
|
|
198
|
+
"{any service flagged NOT_FOUND_IN_LAST_SCAN}",
|
|
199
|
+
"{any new kafka topic discovered by scan}"
|
|
200
|
+
],
|
|
201
|
+
"merge_impact": "MERGE — MCP-owned sections overwritten, workspace sections preserved",
|
|
202
|
+
"previous_mcp_version": "{old npm version}",
|
|
203
|
+
"backup_file": ".secufusion-project-spec.json.backup-{timestamp}"
|
|
32
204
|
}
|
|
33
205
|
```
|
|
34
|
-
2. Update the `<MEMORY>` block in `.agents/claude.md`:
|
|
35
|
-
- Set `DNA_LOADED` to `true`
|
|
36
|
-
- Set `LAST_INIT` to the current ISO timestamp
|
|
37
|
-
- Set `ARCHITECTURE_SUMMARY` to the 2-3 sentence summary from above
|
|
38
206
|
|
|
39
|
-
|
|
207
|
+
**Rule:** `_changelog` is append-only. Never delete an entry. Never modify a past entry.
|
|
208
|
+
The full history must be preserved so any developer can audit exactly what changed
|
|
209
|
+
on their machine and when.
|
|
210
|
+
|
|
211
|
+
6. **Write merged file**
|
|
212
|
+
Write the final merged JSON to workspace root — with the updated `_changelog` included.
|
|
213
|
+
Report what changed:
|
|
214
|
+
|
|
215
|
+
```
|
|
216
|
+
✅ Spec merged: v{old} → v{new}
|
|
217
|
+
|
|
218
|
+
Updated (MCP-owned):
|
|
219
|
+
• golden_rules: {n} rules (was {m})
|
|
220
|
+
• terminology: Device/Machine rules refreshed
|
|
221
|
+
• coding_style: updated
|
|
222
|
+
• platform: updated
|
|
223
|
+
|
|
224
|
+
Preserved + refreshed (workspace-owned):
|
|
225
|
+
• microservices: {n} services ({m} newly discovered)
|
|
226
|
+
• kafka_topics: {n} topics ({m} newly discovered)
|
|
227
|
+
• {service}: flagged NOT_FOUND_IN_LAST_SCAN — verify if service was removed
|
|
40
228
|
|
|
41
|
-
|
|
42
|
-
-
|
|
43
|
-
|
|
44
|
-
- **CRITICAL CORE CHECK:** Explicitly verify that the DNA map contains mappings for **frontend**, **backend**, and **snf-browser-extn** (extension). If ANY of these 3 are missing, print a prominent warning listing exactly what is missing and what needs to be cloned/added.
|
|
45
|
-
- Confirm that `.secufusion/dna.json` was written successfully
|
|
229
|
+
Changelog entry appended: v{new} — {date}
|
|
230
|
+
Backup: .secufusion-project-spec.json.backup-{timestamp}
|
|
231
|
+
```
|
|
46
232
|
|
|
47
|
-
## Phase 4 — ARCHITECTURE DIAGRAM
|
|
48
233
|
|
|
49
|
-
|
|
234
|
+
|
|
235
|
+
### If UP TO DATE (version matches)
|
|
236
|
+
|
|
237
|
+
Do not rewrite the file. Load it and proceed directly to Phase 5.
|
|
238
|
+
Report:
|
|
239
|
+
```
|
|
240
|
+
✅ .secufusion-project-spec.json is current (v{version}) — no changes needed.
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
### Required structure
|
|
246
|
+
|
|
247
|
+
Write a JSON file with this exact top-level shape:
|
|
248
|
+
|
|
249
|
+
```json
|
|
250
|
+
{
|
|
251
|
+
"_meta": {
|
|
252
|
+
"version": "1.0",
|
|
253
|
+
"generated_at": "<ISO timestamp>",
|
|
254
|
+
"generation_source": "/sfn:init scan",
|
|
255
|
+
"warning": "Do not edit manually. Use manage_project_spec(action: update) to modify fields."
|
|
256
|
+
},
|
|
257
|
+
"platform": {
|
|
258
|
+
"name": "<project name>",
|
|
259
|
+
"type": "<platform type from scan>",
|
|
260
|
+
"tenancy_model": "<single-tenant | multi-tenant>",
|
|
261
|
+
"auth_provider": "<Keycloak | Auth0 | etc>",
|
|
262
|
+
"event_bus": "<Kafka | RabbitMQ | none>",
|
|
263
|
+
"database": "<PostgreSQL | MySQL | etc>",
|
|
264
|
+
"migration_strategy": "<MANUAL | Flyway auto | Liquibase>"
|
|
265
|
+
},
|
|
266
|
+
"terminology": {
|
|
267
|
+
"_critical": "Read before touching any entity named Device or Machine.",
|
|
268
|
+
"Device": "A BROWSER INSTALLATION — Chrome, Edge, Firefox on a machine. NOT a physical machine.",
|
|
269
|
+
"Machine": "A PHYSICAL ENDPOINT — laptop, desktop, workstation.",
|
|
270
|
+
"history": "The platform originally used Device to mean physical endpoint. Terminology was corrected in backend services and data models. Older code may still use legacy Device naming for what is now a Machine.",
|
|
271
|
+
"rules": [
|
|
272
|
+
"Before declaring a bug involving 'device': confirm whether it is a Browser (Device) or Physical Endpoint (Machine).",
|
|
273
|
+
"Naming inconsistency does NOT equal a bug — verify which entity is actually referenced.",
|
|
274
|
+
"Frontend labels do NOT map 1:1 to backend entity names."
|
|
275
|
+
]
|
|
276
|
+
},
|
|
277
|
+
"microservices": {
|
|
278
|
+
"<service-name>": {
|
|
279
|
+
"language": "<Java | TypeScript | Go | ...>",
|
|
280
|
+
"framework": "<Spring Boot | Express | ...>",
|
|
281
|
+
"responsibility": "<one sentence>",
|
|
282
|
+
"gateway_route": "<route pattern or NOT_CONFIRMED>",
|
|
283
|
+
"has_database": true,
|
|
284
|
+
"has_migrations": true,
|
|
285
|
+
"migration_path": "src/main/resources/db/migration",
|
|
286
|
+
"migration_notes": "<version gaps or other notes>",
|
|
287
|
+
"kafka_produces": ["<topic-name>"],
|
|
288
|
+
"kafka_consumes": ["<topic-name>"],
|
|
289
|
+
"direct_rest_calls": {
|
|
290
|
+
"<target-service>": "<description and risk>"
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
},
|
|
294
|
+
"frontend": {
|
|
295
|
+
"repo": "<repo name>",
|
|
296
|
+
"language": "<TypeScript | JavaScript>",
|
|
297
|
+
"framework": "<React | Vue | Angular | ...>",
|
|
298
|
+
"gateway_connection": "<how it connects to backend>",
|
|
299
|
+
"terminology_note": "<UX normalization note if applicable>"
|
|
300
|
+
},
|
|
301
|
+
"chrome_extension": {
|
|
302
|
+
"repo": "<repo name>",
|
|
303
|
+
"language": "<Node + Go | ...>",
|
|
304
|
+
"gateway_connection": "<how it connects>",
|
|
305
|
+
"deployment": "<deployment mechanism>"
|
|
306
|
+
},
|
|
307
|
+
"kafka_topics": {
|
|
308
|
+
"<topic-name>": {
|
|
309
|
+
"producers": ["<service>"],
|
|
310
|
+
"consumers": ["<service>"],
|
|
311
|
+
"risk": "<normal | fan-out | two-producers | DEAD TOPIC>"
|
|
312
|
+
}
|
|
313
|
+
},
|
|
314
|
+
"cross_service_call_graph": {
|
|
315
|
+
"<caller> -> <callee>": "<mechanism and risk>"
|
|
316
|
+
},
|
|
317
|
+
"golden_rules": {
|
|
318
|
+
"<rule-id>": {
|
|
319
|
+
"rule": "<the rule>",
|
|
320
|
+
"severity": "<BLOCKER | WARNING>",
|
|
321
|
+
"reason": "<why it exists>"
|
|
322
|
+
}
|
|
323
|
+
},
|
|
324
|
+
"coding_style": {
|
|
325
|
+
"comments": "Explain WHY, never WHAT.",
|
|
326
|
+
"naming": "<casing conventions>",
|
|
327
|
+
"migration_naming": "<pattern>",
|
|
328
|
+
"constraint_naming": "<pattern>"
|
|
329
|
+
},
|
|
330
|
+
"services_with_migrations": ["<service-name>"],
|
|
331
|
+
"services_without_migrations": ["<service-name>"]
|
|
332
|
+
}
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
### Mandatory golden rules to always include
|
|
336
|
+
|
|
337
|
+
Regardless of what the scan finds, always write these rules into `golden_rules`.
|
|
338
|
+
These are non-negotiable on SecuFusion:
|
|
339
|
+
|
|
340
|
+
```json
|
|
341
|
+
"tenant_isolation": { "rule": "Every *Repository.java query method MUST filter by tenantId.", "severity": "BLOCKER" },
|
|
342
|
+
"kafka_no_blocking": { "rule": "@KafkaListener MUST NOT make synchronous HTTP calls or blocking DB writes.", "severity": "BLOCKER" },
|
|
343
|
+
"migration_before_deploy": { "rule": "Every migration script MUST be run via psql BEFORE deploying code that depends on it.", "severity": "BLOCKER" },
|
|
344
|
+
"no_flyway_auto_exec": { "rule": "No spring.flyway.* config. No auto-execution on boot.", "severity": "BLOCKER" },
|
|
345
|
+
"cross_service_timeout": { "rule": "Every RestTemplate/WebClient call MUST have explicit timeout + fallback.", "severity": "BLOCKER" },
|
|
346
|
+
"no_hardcoded_env": { "rule": "No hardcoded IPs, hostnames, ports, URLs, or credentials.", "severity": "BLOCKER" },
|
|
347
|
+
"auth_required": { "rule": "Every non-public controller method MUST have @PreAuthorize.", "severity": "BLOCKER" },
|
|
348
|
+
"no_n_plus_one": { "rule": "No repository calls inside loops.", "severity": "BLOCKER" },
|
|
349
|
+
"index_with_migration": { "rule": "New query columns MUST have CREATE INDEX in the same migration file.", "severity": "BLOCKER" },
|
|
350
|
+
"no_swallowed_exceptions": { "rule": "Empty catch blocks are forbidden. Log, re-throw, or convert.", "severity": "BLOCKER" },
|
|
351
|
+
"device_machine_terminology": { "rule": "Device = Browser. Machine = Physical endpoint. Confirm which entity before touching any code with these names.", "severity": "WARNING" }
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
### After writing the spec
|
|
355
|
+
|
|
356
|
+
Confirm:
|
|
357
|
+
```
|
|
358
|
+
✅ .secufusion-project-spec.json written to {path}
|
|
359
|
+
Services mapped: {count}
|
|
360
|
+
Kafka topics mapped: {count}
|
|
361
|
+
Golden rules written: {count}
|
|
362
|
+
Migration services: {list}
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
---
|
|
366
|
+
|
|
367
|
+
## PHASE 3 — Generate migration spec (only if it does not exist)
|
|
368
|
+
|
|
369
|
+
If `.secufusion-migrations.json` does not exist:
|
|
370
|
+
|
|
371
|
+
For each service in `services_with_migrations`:
|
|
372
|
+
1. Read all `.sql` files in `src/main/resources/db/migration/`
|
|
373
|
+
2. Parse the version numbers (`V{n}__description.sql`)
|
|
374
|
+
3. Identify the highest version number
|
|
375
|
+
4. Identify any gaps in the version sequence (e.g. V1, V2, V4 → gap at V3)
|
|
376
|
+
5. Determine the next suggested version
|
|
377
|
+
|
|
378
|
+
Write `.secufusion-migrations.json` at the workspace root with this structure:
|
|
379
|
+
|
|
380
|
+
```json
|
|
381
|
+
{
|
|
382
|
+
"services": {
|
|
383
|
+
"<service-name>": {
|
|
384
|
+
"has_migrations": true,
|
|
385
|
+
"migration_path": "src/main/resources/db/migration",
|
|
386
|
+
"naming_convention": {
|
|
387
|
+
"pattern": "V{n}__description.sql",
|
|
388
|
+
"examples_spread": ["V1__initial_schema.sql", "V2__add_tenant_id.sql"]
|
|
389
|
+
},
|
|
390
|
+
"content_conventions": {
|
|
391
|
+
"comment_style": "-- ===\n-- V{n}: Description\n-- WHY: Reason\n-- NOTE: Applied MANUALLY\n-- ===",
|
|
392
|
+
"constraint_naming": "chk_{table}_{field} for checks, idx_{table}_{column} for indexes"
|
|
393
|
+
},
|
|
394
|
+
"current_state": {
|
|
395
|
+
"highest_version_number": 5,
|
|
396
|
+
"next_suggested": "V6",
|
|
397
|
+
"all_versions": [1, 2, 3, 4, 5]
|
|
398
|
+
},
|
|
399
|
+
"organization": {
|
|
400
|
+
"version_gaps": [],
|
|
401
|
+
"notes": "No gaps — sequence is clean"
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
},
|
|
405
|
+
"mcp_guardrails": {
|
|
406
|
+
"naming_pattern_to_enforce": "^V\\d+__[a-z][a-z0-9_]*\\.sql$",
|
|
407
|
+
"never_reuse_gap_versions": true,
|
|
408
|
+
"manual_execution_only": true,
|
|
409
|
+
"execution_command": "psql -U <user> -d <database> -f <filename>"
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
Confirm:
|
|
415
|
+
```
|
|
416
|
+
✅ .secufusion-migrations.json written to {path}
|
|
417
|
+
Services with migrations: {list}
|
|
418
|
+
Version gaps found: {list per service}
|
|
419
|
+
```
|
|
420
|
+
|
|
421
|
+
---
|
|
422
|
+
|
|
423
|
+
## PHASE 4 — Generate dna.json (always — or refresh if asked)
|
|
424
|
+
|
|
425
|
+
Write `.secufusion/dna.json` with the combined scan output:
|
|
426
|
+
|
|
427
|
+
```json
|
|
428
|
+
{
|
|
429
|
+
"scannedAt": "<ISO timestamp>",
|
|
430
|
+
"services": [ /* from scan_repository_stack */ ],
|
|
431
|
+
"domainModels": [ /* from extract_domain_models */ ],
|
|
432
|
+
"apiEndpoints": [ /* from extract_api_endpoints */ ],
|
|
433
|
+
"eventTopics": [ /* from extract_event_topics */ ],
|
|
434
|
+
"architectureSummary": "<2-3 sentence human-readable summary of the architecture>"
|
|
435
|
+
}
|
|
436
|
+
```
|
|
437
|
+
|
|
438
|
+
---
|
|
439
|
+
|
|
440
|
+
## PHASE 5 — Update session state
|
|
441
|
+
|
|
442
|
+
Update `.agents/claude.md` MEMORY block:
|
|
443
|
+
|
|
444
|
+
```json
|
|
445
|
+
{
|
|
446
|
+
"DNA_LOADED": true,
|
|
447
|
+
"LAST_INIT": "<ISO timestamp>",
|
|
448
|
+
"ARCHITECTURE_SUMMARY": "<2-3 sentences from architectureSummary above>",
|
|
449
|
+
"ACTIVE_WORK_ITEM": null
|
|
450
|
+
}
|
|
451
|
+
```
|
|
452
|
+
|
|
453
|
+
---
|
|
454
|
+
|
|
455
|
+
## PHASE 6 — Report and diagram
|
|
456
|
+
|
|
457
|
+
### Summary report
|
|
458
|
+
|
|
459
|
+
```
|
|
460
|
+
══════════════════════════════════════════════════════
|
|
461
|
+
SecuFusion Init Complete
|
|
462
|
+
══════════════════════════════════════════════════════
|
|
463
|
+
|
|
464
|
+
Files generated (or already existed):
|
|
465
|
+
✅ .secufusion-project-spec.json — {path}
|
|
466
|
+
✅ .secufusion-migrations.json — {path}
|
|
467
|
+
✅ .secufusion/dna.json — {path}
|
|
468
|
+
✅ .agents/claude.md — DNA_LOADED: true
|
|
469
|
+
|
|
470
|
+
Discovered:
|
|
471
|
+
Services: {count} ({list})
|
|
472
|
+
Domain models: {count} entities
|
|
473
|
+
API endpoints: {count}
|
|
474
|
+
Kafka topics: {count} ({list dead topics with ⚠️})
|
|
475
|
+
Migrations: {services with migrations}
|
|
476
|
+
|
|
477
|
+
Warnings:
|
|
478
|
+
{any inferred routes or unconfirmed connections}
|
|
479
|
+
{any dead Kafka topics}
|
|
480
|
+
{any missing repos per spec expectations}
|
|
481
|
+
|
|
482
|
+
══════════════════════════════════════════════════════
|
|
483
|
+
```
|
|
484
|
+
|
|
485
|
+
### Architecture diagram
|
|
486
|
+
|
|
487
|
+
Generate a Mermaid `graph TD` diagram showing:
|
|
50
488
|
- All microservices and their bounded contexts
|
|
51
|
-
- REST API call graph (which service calls which)
|
|
52
|
-
- Kafka topic flow (producer → topic → consumer)
|
|
53
|
-
- Frontend and
|
|
489
|
+
- REST API call graph (which service calls which, including direct bypass calls)
|
|
490
|
+
- Kafka topic flow (producer → topic → consumer, flag dead topics with ⚠️)
|
|
491
|
+
- Frontend and extension connections to backend
|
|
492
|
+
|
|
493
|
+
Render the diagram in your response.
|
|
494
|
+
|
|
495
|
+
---
|
|
496
|
+
|
|
497
|
+
## PHASE 7 — Handover instructions for new developers
|
|
498
|
+
|
|
499
|
+
After generating everything, output this exactly:
|
|
500
|
+
|
|
501
|
+
```
|
|
502
|
+
══════════════════════════════════════════════════════
|
|
503
|
+
WORKSPACE READY
|
|
504
|
+
|
|
505
|
+
All memory files generated. This workspace is now
|
|
506
|
+
fully primed for SecuFusion MCP tooling.
|
|
507
|
+
|
|
508
|
+
Important files created:
|
|
509
|
+
• .secufusion-project-spec.json — permanent project memory
|
|
510
|
+
• .secufusion-migrations.json — migration version tracking
|
|
511
|
+
• .secufusion/dna.json — architectural scan results
|
|
512
|
+
|
|
513
|
+
These files are generated from your local source code.
|
|
514
|
+
They are safe to commit to the repo so teammates get
|
|
515
|
+
them pre-populated on clone.
|
|
54
516
|
|
|
55
|
-
|
|
517
|
+
Next steps:
|
|
518
|
+
• To start a task: /sfn:plan <WI-ID>
|
|
519
|
+
• To review code: /sfn:review <WI-ID>
|
|
520
|
+
• To refresh DNA: /sfn:init (safe — will not overwrite existing spec)
|
|
56
521
|
|
|
57
|
-
|
|
522
|
+
If you cloned this repo and these files already exist:
|
|
523
|
+
• You do not need to run /sfn:init
|
|
524
|
+
• The MCP is already primed and ready
|
|
525
|
+
• Run /sfn:plan <your-ticket> to start working
|
|
526
|
+
══════════════════════════════════════════════════════
|
|
527
|
+
```
|