codeninja 3.1.0 → 4.0.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.
Files changed (111) hide show
  1. package/README.md +13 -1
  2. package/agent/database-agent.md +24 -1
  3. package/agent/nodejs-agent.md +79 -0
  4. package/cli.js +27 -7
  5. package/commands/audit.workflow.md +4 -1
  6. package/commands/db-create-table.workflow.md +1 -1
  7. package/commands/initialize-project.workflow.md +21 -0
  8. package/ide/antigravity/.agents/personas/database-architect.md +431 -153
  9. package/ide/antigravity/.agents/personas/global-orchestrator.md +219 -83
  10. package/ide/antigravity/.agents/personas/nodejs-backend.md +368 -133
  11. package/ide/antigravity/.agents/personas/reactjs-frontend.md +182 -101
  12. package/ide/antigravity/.agents/skills/api-builder/SKILL.md +58 -0
  13. package/ide/antigravity/.agents/skills/code-intelligence/SKILL.md +22 -0
  14. package/ide/antigravity/.agents/skills/database/SKILL.md +32 -0
  15. package/ide/antigravity/.agents/skills/mcp-and-context/SKILL.md +76 -82
  16. package/ide/antigravity/.agents/skills/reactjs/SKILL.md +36 -0
  17. package/ide/antigravity/.agents/workflows/codeninja-api.md +97 -21
  18. package/ide/antigravity/.agents/workflows/codeninja-audit.md +112 -16
  19. package/ide/antigravity/.agents/workflows/codeninja-db-create.md +135 -9
  20. package/ide/antigravity/.agents/workflows/codeninja-db-drop.md +107 -9
  21. package/ide/antigravity/.agents/workflows/codeninja-db-index.md +100 -9
  22. package/ide/antigravity/.agents/workflows/codeninja-db-modify.md +162 -9
  23. package/ide/antigravity/.agents/workflows/codeninja-db-seed.md +102 -8
  24. package/ide/antigravity/.agents/workflows/codeninja-db-sync.md +105 -11
  25. package/ide/antigravity/.agents/workflows/codeninja-debug.md +94 -10
  26. package/ide/antigravity/.agents/workflows/codeninja-design.md +61 -14
  27. package/ide/antigravity/.agents/workflows/codeninja-explain.md +59 -9
  28. package/ide/antigravity/.agents/workflows/codeninja-init.md +518 -21
  29. package/ide/antigravity/.agents/workflows/codeninja-integrate-api.md +451 -9
  30. package/ide/antigravity/.agents/workflows/codeninja-modularize.md +332 -9
  31. package/ide/antigravity/.agents/workflows/codeninja-optimize.md +124 -11
  32. package/ide/antigravity/.agents/workflows/codeninja-refactor.md +69 -16
  33. package/ide/antigravity/.agents/workflows/codeninja-review.md +85 -10
  34. package/ide/antigravity/.agents/workflows/codeninja-sync.md +957 -16
  35. package/ide/antigravity/.agents/workflows/codeninja-test.md +40 -13
  36. package/ide/antigravity/.agents/workflows/codeninja-validate-page.md +546 -9
  37. package/ide/claude-code/.claude/CLAUDE.md +99 -0
  38. package/ide/claude-code/.claude/agents/database-agent.md +535 -0
  39. package/ide/claude-code/.claude/agents/nodejs-agent.md +493 -0
  40. package/ide/claude-code/.claude/agents/reactjs-agent.md +267 -0
  41. package/ide/claude-code/.claude/commands/codeninja-api.md +104 -0
  42. package/ide/claude-code/.claude/commands/codeninja-audit.md +119 -0
  43. package/ide/claude-code/.claude/commands/codeninja-db-create.md +138 -0
  44. package/ide/claude-code/.claude/commands/codeninja-db-drop.md +109 -0
  45. package/ide/claude-code/.claude/commands/codeninja-db-index.md +103 -0
  46. package/ide/claude-code/.claude/commands/codeninja-db-modify.md +165 -0
  47. package/ide/claude-code/.claude/commands/codeninja-db-seed.md +104 -0
  48. package/ide/claude-code/.claude/commands/codeninja-db-sync.md +106 -0
  49. package/ide/claude-code/.claude/commands/codeninja-debug.md +99 -0
  50. package/ide/claude-code/.claude/commands/codeninja-design.md +68 -0
  51. package/ide/claude-code/.claude/commands/codeninja-explain.md +61 -0
  52. package/ide/claude-code/.claude/commands/codeninja-init.md +529 -0
  53. package/ide/claude-code/.claude/commands/codeninja-integrate-api.md +453 -0
  54. package/ide/claude-code/.claude/commands/codeninja-modularize.md +334 -0
  55. package/ide/claude-code/.claude/commands/codeninja-optimize.md +129 -0
  56. package/ide/claude-code/.claude/commands/codeninja-refactor.md +76 -0
  57. package/ide/claude-code/.claude/commands/codeninja-review.md +87 -0
  58. package/ide/claude-code/.claude/commands/codeninja-sync.md +964 -0
  59. package/ide/claude-code/.claude/commands/codeninja-test.md +45 -0
  60. package/ide/claude-code/.claude/commands/codeninja-validate-page.md +548 -0
  61. package/ide/cursor/.cursor/rules/01-global-orchestrator.mdc +40 -38
  62. package/ide/cursor/.cursor/rules/02-mcp-and-context.mdc +47 -31
  63. package/ide/cursor/.cursor/rules/03-api-builder.mdc +30 -58
  64. package/ide/cursor/.cursor/rules/04-nodejs-generation.mdc +58 -0
  65. package/ide/cursor/.cursor/rules/05-database.mdc +54 -0
  66. package/ide/cursor/.cursor/rules/06-reactjs.mdc +36 -0
  67. package/ide/cursor/.cursor/rules/07-reactjs-generation.mdc +49 -0
  68. package/ide/cursor/.cursor/rules/08-code-intelligence.mdc +56 -0
  69. package/ide/cursor/.cursor/rules/09-workflow-steps.mdc +53 -0
  70. package/ide/vscode/.github/copilot-instructions.md +69 -270
  71. package/ide/vscode/.vscode/instructions/code-intelligence.instructions.md +58 -0
  72. package/ide/vscode/.vscode/instructions/database.instructions.md +55 -0
  73. package/ide/vscode/.vscode/instructions/nodejs.instructions.md +77 -0
  74. package/ide/vscode/.vscode/instructions/reactjs.instructions.md +42 -0
  75. package/package.json +2 -2
  76. package/tasks/ask-hashing-library.task.md +31 -0
  77. package/tasks/ask-language-type.task.md +26 -0
  78. package/tasks/ask-new-module-name.task.md +13 -0
  79. package/tasks/ask-new-service-name.task.md +13 -0
  80. package/tasks/ask-old-module-name.task.md +15 -0
  81. package/tasks/ask-old-service-name.task.md +13 -0
  82. package/tasks/ask-orm-type.task.md +26 -0
  83. package/tasks/collect-seed-data.task.md +19 -0
  84. package/tasks/generate-app.task.md +42 -0
  85. package/tasks/generate-common.task.md +13 -0
  86. package/tasks/generate-constants.task.md +13 -0
  87. package/tasks/generate-database.task.md +32 -0
  88. package/tasks/generate-encryption.task.md +28 -0
  89. package/tasks/generate-fast-defaults.task.md +7 -0
  90. package/tasks/generate-hashing.task.md +180 -0
  91. package/tasks/generate-headerValidator.task.md +13 -0
  92. package/tasks/generate-ioRedis.task.md +20 -0
  93. package/tasks/generate-language-en.task.md +12 -0
  94. package/tasks/generate-logging.task.md +12 -0
  95. package/tasks/generate-model.task.md +74 -6
  96. package/tasks/generate-notification.task.md +12 -0
  97. package/tasks/generate-package-json.task.md +69 -0
  98. package/tasks/generate-prisma-client.task.md +56 -0
  99. package/tasks/generate-prisma-schema.task.md +71 -0
  100. package/tasks/generate-rateLimiter.task.md +20 -0
  101. package/tasks/generate-readme.task.md +24 -0
  102. package/tasks/generate-response.task.md +27 -0
  103. package/tasks/generate-route-manager.task.md +32 -0
  104. package/tasks/generate-route.task.md +37 -0
  105. package/tasks/generate-swagger.task.md +8 -0
  106. package/tasks/generate-template.task.md +12 -0
  107. package/tasks/generate-tsconfig.task.md +38 -0
  108. package/tasks/generate-validator.task.md +31 -0
  109. package/ide/cursor/.cursor/rules/04-database.mdc +0 -87
  110. package/ide/cursor/.cursor/rules/05-reactjs.mdc +0 -83
  111. package/ide/cursor/.cursor/rules/06-code-intelligence.mdc +0 -112
@@ -1,23 +1,964 @@
1
+ This workflow runs when user invokes /codeninja:sync
2
+
3
+ ---
4
+ type: workflow
5
+ name: sync
6
+ description: >
7
+ Scans the entire repository and builds or rebuilds context.json from
8
+ what actually exists on disk. Works on both agent-initialized projects
9
+ and pre-existing legacy projects with completely different structures.
10
+ Always writes context.json — creates it if missing. Safe to run at any time.
11
+ ---
12
+
13
+ # Workflow: @sync
14
+
15
+ ## Goal
16
+ Make context.json an accurate, complete reflection of the current
17
+ repository — whether the project was initialized by this agent or
18
+ existed long before this system was introduced.
19
+
20
+ ALWAYS write context.json at the end of every sync run.
21
+ If context.json does not exist → create it from scratch using the
22
+ empty schema from write-context.task.md and populate it from scan results.
23
+ Never skip the write step even if nothing changed.
24
+
25
+ ---
26
+
27
+ ## Two Operating Modes
28
+
29
+ Sync detects which mode to use automatically. Do not ask the user.
30
+
31
+ ### Mode A — Agent-Initialized Project
32
+ Indicators: `.codeninja/context/context.json` exists AND has
33
+ `context_version > 0` AND `context.services` has at least one entry.
34
+
35
+ In this mode: trust context.json as a baseline, scan for drift and
36
+ gaps, merge new findings into existing context without overwriting
37
+ known-good values.
38
+
39
+ ### Mode B — Legacy / No-Context Project
40
+ Indicators: context.json is missing OR `context_version == 0` OR
41
+ `context.services` is empty.
42
+
43
+ In this mode: treat every discovery as new. Build context.json
44
+ entirely from what is found on disk. Make no assumptions about
45
+ structure — the project may follow completely different conventions
46
+ from the agent's own generated patterns. Be inventive and read deeply.
47
+
48
+ ---
49
+
50
+ ## Core Rules (apply to both modes)
51
+
52
+ - ALWAYS write context.json at the end — no exceptions
53
+ - NEVER delete existing context entries — only add or update
54
+ - NEVER assume a file will be in a specific location — scan first
55
+ - NEVER assume a project follows agent conventions — verify everything
56
+ - Preserve all existing `change_log` entries — append only
57
+ - Report all findings in the sync report at the end
58
+ - If a value conflicts with what is already in context → list it and
59
+ ask user to confirm which to keep — one conflict at a time — before
60
+ writing context
61
+
62
+ ---
63
+
64
+ ## Step-by-Step Execution
65
+
66
+ ---
67
+
68
+ ### Phase 0 — Determine Mode and Prepare
69
+
70
+ 0a. Check if `.codeninja/context/` directory exists.
71
+ If not → create it now. Do not fail on missing directory.
72
+
73
+ 0b. Attempt to read context.json via MCP tool `context_read`.
74
+ If it returns the empty schema (context_version == 0) or fails →
75
+ set mode = B and prepare a fresh empty schema in memory.
76
+ If it returns data with context_version > 0 and populated services →
77
+ set mode = A and load all existing values as the working baseline.
78
+
79
+ 0c. Run task: `detect-repository-state`
80
+ This scans root for service folders, database folder, and
81
+ React apps regardless of mode.
82
+
83
+ 0d. Determine sync report counters — initialize all to zero:
84
+ services_synced, routes_discovered, routes_new,
85
+ db_tables_synced, db_tables_new, gaps_filled, unchanged,
86
+ legacy_inferences
87
+
88
+ ---
89
+
90
+ ### Phase 1 — Repository Structure Discovery
91
+
92
+ This phase maps every part of the repository before any context
93
+ is written. Read first, write later.
94
+
95
+ #### 1a — Find all service-like directories
96
+
97
+ Scan every directory at repository root. A directory is a candidate
98
+ service if it contains ANY of these signals:
99
+ - `package.json` (Node/React project)
100
+ - `app.js` or `index.js` (Node entry points)
101
+ - `src/` directory (could be React or modern Node)
102
+ - `composer.json` (PHP project — record but do not deep-scan)
103
+ - `requirements.txt` or `pyproject.toml` (Python — record, note unsupported)
104
+ - `Gemfile` (Ruby — record, note unsupported)
105
+ - `pom.xml` or `build.gradle` (Java — record, note unsupported)
106
+
107
+ For each candidate directory: record name and what signal triggered it.
108
+
109
+ Skip: `.codeninja/`, `node_modules/`, `.git/`, `dist/`, `build/`,
110
+ `.next/`, `.nuxt/`, `coverage/`, `.cache/`
111
+
112
+ #### 1b — Classify each candidate
113
+
114
+ For each candidate directory, determine its tech type:
115
+
116
+ **NodeJS detection (check in order):**
117
+ 1. `package.json` exists → read it
118
+ 2. Check `dependencies` for: express, fastify, koa, hapi, nestjs
119
+ 3. Check for `app.js`, `server.js`, `index.js` at root of directory
120
+ 4. Check for `src/app.js` or `src/index.js`
121
+ → If any match: classify as `nodejs`
122
+
123
+ **ReactJS detection (check in order):**
124
+ 1. `package.json` exists → read it
125
+ 2. Check `dependencies` or `devDependencies` for: react, react-dom
126
+ 3. Check for `src/App.jsx`, `src/App.js`, `src/App.tsx`
127
+ 4. Check for `src/index.jsx`, `src/index.js`, `src/main.jsx`
128
+ 5. Check for `public/index.html`
129
+ → If any match: classify as `reactjs`
130
+ Note: If both express AND react are in the same package.json →
131
+ classify as `nodejs` and note the React dependency as unusual.
132
+
133
+ **Unknown:** Record the folder, note what was found, do not classify.
134
+
135
+ #### 1c — Find the database directory
136
+
137
+ Search for database files using ALL of the following patterns —
138
+ not just the agent's convention of `database/` at root:
139
+
140
+ - `database/` at repository root (agent convention)
141
+ - `db/` at repository root
142
+ - `<service_name>/database/` inside any service folder
143
+ (misplaced — flag it)
144
+ - `<service_name>/db/` inside any service folder
145
+ (misplaced — flag it)
146
+ - `migrations/` at repository root or inside any service
147
+ - `schema/` at repository root or inside any service
148
+ - `sql/` at repository root or inside any service
149
+ - Any `.sql` files anywhere in the repo
150
+ - For MongoDB: `models/` directories containing Mongoose schema
151
+ files (files with `mongoose.Schema` or `new Schema(`)
152
+ - For MongoDB: any `*.model.js` files with Schema definitions
153
+
154
+ Record all database locations found. The agent's expected location
155
+ is `database/<db_type>/migrations/` — anything else is noted in
156
+ the report as non-standard but still scanned.
157
+
158
+ #### 1d — Find shared infrastructure
159
+
160
+ Scan for files that exist outside service folders and may be shared:
161
+ - `docker-compose.yml` or `docker-compose.yaml`
162
+ - `Dockerfile` at root
163
+ - `.env` at root (shared environment)
164
+ - `nginx.conf` or `nginx/`
165
+ - `kubernetes/` or `k8s/`
166
+ - `scripts/` at root
167
+ - `docs/` or `documentation/`
168
+ - `README.md` at root
169
+
170
+ Record all found. These do not create service entries but inform
171
+ the project_info summary.
172
+
173
+ ---
174
+
175
+ ### Phase 2 — Deep Scan Each NodeJS Service
176
+
177
+ For each directory classified as `nodejs` in Phase 1:
178
+
179
+ #### 2a — Identity and Package
180
+
181
+ Read `package.json` → extract:
182
+ - `name` → candidate for service_name
183
+ - `version`
184
+ - `description`
185
+ - `author`
186
+ - `main` → note actual entry point
187
+ - `scripts` → note start script key and value
188
+ - All `dependencies` → full list
189
+ - All `devDependencies` → full list
190
+
191
+ If `package.json` not found → use directory name as service_name.
192
+
193
+ #### 2b — Find the Entry Point
194
+
195
+ The entry point is NOT always `app.js`. Check in this order:
196
+ 1. `package.json` `main` field
197
+ 2. `package.json` `scripts.start` → extract filename from `node <file>`
198
+ 3. `app.js` at service root
199
+ 4. `server.js` at service root
200
+ 5. `index.js` at service root
201
+ 6. `src/app.js`
202
+ 7. `src/index.js`
203
+
204
+ Read the entry point file → extract:
205
+ - Port: scan for `process.env.PORT`, `.listen(`, `PORT =`
206
+ - Middleware registrations (look for `app.use(`)
207
+ - Route registrations (look for `app.use('/', `, `require(`)
208
+ - Any `dotenv` or `dotenv.config()` call
209
+
210
+ #### 2c — Find Environment Config
211
+
212
+ Search for `.env` file in this order:
213
+ 1. `<service>/.env`
214
+ 2. `<service>/.env.local`
215
+ 3. `<service>/.env.development`
216
+ 4. `.env` at repository root
217
+
218
+ If found → read all key=value pairs. Extract:
219
+ - PORT → service port
220
+ - PROJECT_NAME or APP_NAME or SERVICE_NAME → service name hint
221
+ - API_KEY or APIKEY → api_key
222
+ - KEY, ENCRYPTION_KEY, SECRET_KEY, APP_KEY → encryption_key
223
+ - IV, ENCRYPTION_IV, SECRET_IV → encryption_iv
224
+ - ENCRYPTED_TRANSPORT → encrypted_transport (parse as boolean)
225
+ - SUPPORTED_LANGUAGES, LANGUAGES → parse as array
226
+ - DB_HOST, DATABASE_HOST, PGHOST, MYSQL_HOST → db host
227
+ - DB_PORT, DATABASE_PORT, PGPORT, MYSQL_PORT → db port
228
+ - DB_NAME, DATABASE_NAME, PGDATABASE, MYSQL_DATABASE → db name
229
+ - DB_USER, DATABASE_USER, PGUSER, MYSQL_USER → db user
230
+ - DB_PASSWORD, DATABASE_PASSWORD, PGPASSWORD → note exists (never store value)
231
+ - REDIS_HOST, REDIS_URL → redis host
232
+ - REDIS_PORT → redis port
233
+
234
+ If `.env` not found → also check `.env.example` for key names
235
+ (even if values are blank, it documents what the service expects).
236
+
237
+ #### 2d — Find Route Definitions
238
+
239
+ Routes may live in many structures. Scan all of these:
240
+
241
+ **Agent-convention structure:**
242
+ - `modules/v1/<ModuleName>/route.js`
243
+ - `modules/v2/<ModuleName>/route.js`
244
+
245
+ **Common legacy structures:**
246
+ - `routes/<n>.js` or `routes/<n>.route.js`
247
+ - `routes/v1/<n>.js`
248
+ - `src/routes/<n>.js`
249
+ - `api/routes/<n>.js`
250
+ - `controllers/<n>.js` (routes may be defined here in some patterns)
251
+ - `src/controllers/<n>.js`
252
+ - Any file named `*.router.js`, `*.routes.js`, `route.js`, `router.js`
253
+
254
+ For each route file found → extract:
255
+ - HTTP method: `router.get`, `router.post`, `router.put`,
256
+ `router.patch`, `router.delete`, `app.get`, `app.post`, etc.
257
+ - Route path: the string argument (e.g. `/login`, `/users/:id`)
258
+ - Handler name or comment if present
259
+ - Version prefix if detectable from folder or router mount path
260
+
261
+ Also read the entry point for `app.use('/v1', ...)` style mounts to
262
+ determine base prefix for routes.
263
+
264
+ #### 2e — Determine Encryption Library and Client Type
265
+
266
+ Scan for encryption setup. Do NOT assume a specific file location:
267
+ - Search all `.js` files for: `require('crypto-js')`,
268
+ `require("crypto-js")`, `import CryptoJS`
269
+ - Search for: `require('cryptlib')`, `require("cryptlib")`,
270
+ `import cryptlib`
271
+ - Search for: `require('crypto')` (Node built-in AES — different approach)
272
+ - Search for: `CryptoJS.AES`, `cryptlib.encrypt`, `crypto.createCipheriv`
273
+
274
+ Also check for the encryption/decryption pattern inline in other files:
275
+ - `headerValidator.js`, `common.js`, `app.js`, any middleware file
276
+ may contain the encrypt/decrypt logic directly in older projects
277
+
278
+ Map findings to client_type:
279
+ - crypto-js found → `client_type = "reactjs"`
280
+ - cryptlib found → `client_type = "app"`
281
+ - Node crypto with AES → `client_type = "app"` (note: custom implementation)
282
+ - Nothing found → `client_type = null` (record as unknown)
283
+
284
+ Also look for encrypted transport pattern:
285
+ - Any middleware that calls `decrypt(req.body)` or similar before
286
+ passing to handlers → `encrypted_transport = true`
287
+ - Check ENCRYPTED_TRANSPORT in .env as backup
288
+ - If neither found → `encrypted_transport = false`
289
+
290
+ #### 2f — Detect DB Driver and Type
291
+
292
+ Scan `package.json` dependencies AND all `require()`/`import`
293
+ statements across the service for:
294
+ - `pg` or `pg-pool` or `postgres` → `db_type = "postgresql"`
295
+ - `mysql` or `mysql2` → `db_type = "mysql"`
296
+ - `mongoose` or `mongodb` → `db_type = "mongodb"`
297
+ - `better-sqlite3` or `sqlite3` → `db_type = "sqlite"` (note: not fully supported)
298
+ - `knex` or `sequelize` or `typeorm` or `prisma` →
299
+ note ORM found, attempt to infer underlying DB from config files
300
+
301
+ Also check `config/database.js`, `config/db.js`, `database.js`,
302
+ `src/config/database.js`, `db/index.js`, `src/db/index.js` for
303
+ connection config strings that reveal the DB type.
304
+
305
+ #### 2g — Detect Middleware Stack
306
+
307
+ Do NOT assume agent-convention filenames. Instead, scan for
308
+ middleware by behavior:
309
+
310
+ Scan `app.use(` calls in the entry point AND any route manager /
311
+ router index files. Also scan all files in:
312
+ - `middleware/`
313
+ - `middlewares/`
314
+ - `src/middleware/`
315
+ - Any file named `*middleware*`, `*validator*`, `*auth*`, `*guard*`
316
+
317
+ For each middleware file found, classify by behavior:
318
+ - Reads `api-key` or `x-api-key` header and validates it →
319
+ record as `api_key_validator`
320
+ - Reads `Authorization` header or verifies JWT →
321
+ record as `auth_validator`
322
+ - Calls `req.ip` and tracks request counts →
323
+ record as `rate_limiter`
324
+ - Extracts language from header (Accept-Language, lang, language) →
325
+ record as `language_extractor`
326
+ - Decrypts `req.body` using AES or similar →
327
+ record as `decrypt_request`
328
+
329
+ In legacy projects the functions above may all be in a single file
330
+ (e.g. `common.js`, `headerValidator.js`, `app.js` directly).
331
+ Classify by the behavior found, not by the filename.
332
+
333
+ #### 2h — Detect Language / i18n Setup
334
+
335
+ Scan for any of these i18n patterns:
336
+ - `languages/` directory with `*.js` files → read all filenames
337
+ - `locales/` directory with `*.json` files → read all filenames
338
+ - `i18n/` directory
339
+ - `localizify` in package.json → agent convention confirmed
340
+ - `i18next`, `vue-i18n`, `react-intl` in package.json → note library
341
+ - Any `require('../languages/')` or `require('./locales/')` references
342
+
343
+ For `languages/` files → extract language code from filename
344
+ (e.g. `en.js`, `ar.js`, `fr.js`) → build `supported_languages[]`
345
+
346
+ #### 2i — Read Config Files (wherever they are)
347
+
348
+ Do NOT look only in `config/`. Search for configuration across:
349
+ - `config/*.js` (agent convention)
350
+ - `src/config/*.js`
351
+ - `settings.js`, `settings/index.js`
352
+ - `constants.js`, `src/constants.js`, `config/constants.js`
353
+ - `common.js`, `config/common.js`
354
+
355
+ From these files extract:
356
+ - Any hardcoded port references
357
+ - Any API version declarations (v1, v2)
358
+ - Any service name or project name constants
359
+ - Any feature flags
360
+
361
+ #### 2j — Detect Redis Usage
362
+
363
+ Scan for Redis client setup anywhere:
364
+ - `require('ioredis')`, `require('redis')`, `require("ioredis")`
365
+ - `new Redis(`, `redis.createClient(`
366
+ - Check extracted .env values for REDIS_HOST, REDIS_PORT
367
+
368
+ #### 2k — Classify Service vs Agent-Initialized
369
+
370
+ After all scans for this service, determine:
371
+
372
+ **Agent-initialized** if ALL of these are true:
373
+ - `modules/v1/` directory exists
374
+ - `utilities/` directory exists with at least encryption.js and response.js
375
+ - `middleware/` directory exists with headerValidator.js
376
+ - `.codeninja/context/context.json` has an entry for this service
377
+
378
+ **Legacy** if ANY of the above is false.
379
+
380
+ Record the classification. Legacy services get a note in the sync
381
+ report. Neither classification affects how the service is synced —
382
+ both are fully scanned and registered in context.
383
+
384
+ ---
385
+
386
+ ### Phase 3 — Deep Scan Each ReactJS Service
387
+
388
+ For each directory classified as `reactjs` in Phase 1:
389
+
390
+ #### 3a — Identity and Package
391
+
392
+ Read `package.json` → extract name, description, version, scripts.
393
+ Note all dependencies.
394
+
395
+ #### 3b — Find Entry and Port
396
+
397
+ Look for dev server port in:
398
+ - `package.json` `scripts.start` (e.g. `PORT=3001 react-scripts start`)
399
+ - `.env` → `PORT` or `REACT_APP_PORT`
400
+ - `vite.config.js` or `vite.config.ts` → `server.port`
401
+ - `webpack.config.js` → `devServer.port`
402
+ - Default: 3000
403
+
404
+ #### 3c — Find API Integration
405
+
406
+ Determine what backend this React app talks to:
407
+ - `.env` → look for keys containing: BASE_URL, API_URL, API_BASE,
408
+ REACT_APP_BASE_URL, VITE_API_URL, VUE_APP_API_URL
409
+ - Extract hostname/port from those values
410
+ - Match the port against all known NodeJS services in current scan
411
+ to identify the `linked_service`
412
+ - Also scan `src/api/`, `src/services/`, `src/utils/`, `src/helpers/`
413
+ for axios/fetch base URL declarations (e.g. `baseURL:`, `axios.create(`,
414
+ `fetch('http`, `const API_URL =`, `const BASE_URL =`)
415
+
416
+ #### 3d — Find Page / Route Structure
417
+
418
+ Scan for React Router or equivalent:
419
+ - `src/App.jsx`, `src/App.js`, `src/App.tsx` → extract `<Route` declarations
420
+ - `src/router/`, `src/routes/` → extract route configs
421
+ - `src/pages/` → list subdirectories as page names
422
+ - `src/views/` → list subdirectories as view names
423
+ - `src/screens/` → list subdirectories (common in React Native style)
424
+
425
+ #### 3e — Find Encryption Setup
426
+
427
+ Scan for crypto-js usage in src/:
428
+ - Any `require('crypto-js')` or `import CryptoJS`
429
+ - Any `CryptoJS.AES.encrypt` / `CryptoJS.AES.decrypt` calls
430
+ - Check for these in: api/, utils/, services/, config/ subdirs
431
+ - In legacy React: may be in a standalone `utils/encryption.js` or
432
+ `helpers/crypto.js` or even inline in an axios interceptor
433
+
434
+ #### 3f — Classify as Agent-Initialized or Legacy
435
+
436
+ **Agent-initialized** if ALL true:
437
+ - `src/api/apiClient.js` exists
438
+ - `src/api/apiHandler.js` exists
439
+ - `.env` has REACT_APP_KEY, REACT_APP_IV, REACT_APP_API_KEY
440
+
441
+ **Legacy** if any of the above is false.
442
+
443
+ ---
444
+
445
+ ### Phase 4 — Deep Scan Database
446
+
447
+ For each database location found in Phase 1c:
448
+
449
+ #### 4a — Determine Database Type
450
+
451
+ If not already determined from service scans:
452
+ - Check folder name: `postgresql/`, `postgres/`, `mysql/`, `mongodb/`
453
+ - Check file extensions: `.sql` → relational; `.js` with Schema → MongoDB
454
+ - Check first SQL file header comments
455
+ - Check for `CREATE TABLE` → SQL-based
456
+ - Check for `mongoose.Schema` or `new Schema(` → MongoDB
457
+
458
+ #### 4b — Parse SQL Migration Files
459
+
460
+ For SQL databases, scan ALL `.sql` files regardless of naming convention.
461
+ Do NOT require the agent's `N-setup-tbl-*.sql` naming pattern.
462
+
463
+ For each `.sql` file found, parse for:
464
+
465
+ **CREATE TABLE statements:**
466
+ - Extract table name (remove schema prefix if present, e.g. `public.`)
467
+ - Extract all column definitions:
468
+ - Column name
469
+ - Data type (normalize to lowercase)
470
+ - Constraints (NOT NULL, DEFAULT, CHECK, UNIQUE)
471
+ - PRIMARY KEY columns
472
+ - Extract inline index definitions
473
+ - Note any seed INSERT statements in the same file
474
+
475
+ **ALTER TABLE statements:**
476
+ - ADD COLUMN → record column addition with table name
477
+ - RENAME COLUMN → record rename (from → to) with table name
478
+ - DROP COLUMN → record column removal with table name
479
+ - ADD CONSTRAINT → record constraint addition
480
+ - Modify type → record type change
481
+
482
+ **CREATE INDEX statements:**
483
+ - Extract index name, table name, columns
484
+
485
+ **DROP TABLE statements:**
486
+ - Record that the table was dropped
487
+
488
+ Apply changes in file sort order:
489
+ - Try numeric prefix first: `1-*.sql`, `2-*.sql`, etc.
490
+ - Try timestamp prefix: `20240101_*.sql`
491
+ - Try V-prefix Flyway style: `V1__*.sql`, `V2__*.sql`
492
+ - If no order can be determined → process alphabetically and note it
493
+
494
+ Build the final effective schema state from all migrations in order.
495
+ The last state is what goes into `context.db.schema.tables`.
496
+
497
+ #### 4c — Parse MongoDB Schema Files
498
+
499
+ For MongoDB, scan ALL files for mongoose Schema definitions.
500
+
501
+ For each Schema found → extract:
502
+ - Model name (from `mongoose.model('ModelName', schema)`)
503
+ - All field definitions with types and constraints
504
+ - Indexes defined with `schema.index()`
505
+
506
+ Convert model name to snake_case for context key.
507
+ Example: `UserBot` → stored as `user_bots`
508
+
509
+ #### 4d — Find Non-Standard Schema Definitions
510
+
511
+ For legacy projects that define schema in code rather than files:
512
+
513
+ Scan ALL JavaScript files for ORM model definitions:
514
+ - Sequelize: `sequelize.define('model', {...})` or `DataTypes.*` in object
515
+ - TypeORM: `@Entity()`, `@Column()` decorators
516
+ - Prisma: check `prisma/schema.prisma`
517
+ - Knex: check migration files in any `migrations/` folder
518
+
519
+ For each found → extract model/table name and column list as best
520
+ as possible. Note in sync report that schema was inferred from ORM
521
+ definitions, not raw SQL.
522
+
523
+ #### 4e — Infer Schema From Query Patterns (last resort)
524
+
525
+ If no migration files, schema files, or ORM models are found, but
526
+ a database driver IS present in the service:
527
+
528
+ Scan all model files (`*_model.js`, `*Model.js`, `*model.js`,
529
+ files in `models/` directories) for SQL query strings:
530
+ - `SELECT * FROM <table>` → table name hint
531
+ - `INSERT INTO <table>` → table name hint
532
+ - Column names in SELECT lists → column hints
533
+ - Column names in WHERE clauses → column hints
534
+
535
+ This is low-confidence data. Tag all values inferred this way as
536
+ `confidence: "low"` and list them clearly in the sync report as
537
+ requiring manual verification.
538
+
539
+ ---
540
+
541
+ ### Phase 5 — Infer Cross-Service Relationships
542
+
543
+ After scanning all services individually, look for connections:
544
+
545
+ #### 5a — ReactJS → NodeJS linking
546
+
547
+ For each ReactJS service:
548
+ - Take the extracted API base URL port from Phase 3c
549
+ - Find the NodeJS service whose port matches
550
+ - Set `linked_service` to that service's name
551
+ - If no match found → note as "unlinked frontend" in sync report
552
+
553
+ #### 5b — Shared Database
554
+
555
+ Check if multiple services share the same DB connection config
556
+ (same host, port, name) → they share a database. Note this in report.
557
+
558
+ #### 5c — Port Inventory
559
+
560
+ Build a complete port registry across all services found.
561
+ Check for port conflicts (two services on the same port).
562
+ If conflict found → flag in sync report as requires manual resolution.
563
+
564
+ #### 5d — Shared Utilities or Libraries
565
+
566
+ Check if any service directories import from each other or from a
567
+ shared `lib/`, `shared/`, or `common/` directory at repository root.
568
+ Note shared dependencies in the sync report — they may indicate
569
+ a monorepo pattern that context should record.
570
+
571
+ #### 5e — Environment Variable Cross-References
572
+
573
+ If multiple services have `.env` files, check whether any service
574
+ references another service's port in its config
575
+ (e.g. one service's REDIS_HOST pointing to another service's host).
576
+ Record these links as `service_dependencies` in context.
577
+
578
+ ---
579
+
580
+ ### Phase 6 — Conflict Resolution
581
+
582
+ Before writing context, check for conflicts between scan results
583
+ and existing context (Mode A only — skip in Mode B):
584
+
585
+ For each discovered value that differs from an existing context value:
586
+ - Collect all conflicts into a list
587
+ - Show the user a conflict summary with current vs discovered values
588
+ - Ask user to confirm which to keep, ONE conflict at a time
589
+ - Do not write context until all conflicts are resolved
590
+
591
+ Example conflict:
592
+ "Port for service 'auth' in context.json: 1001
593
+ Port found in auth/.env on disk: 1002
594
+ Which is correct? (context / disk)"
595
+
596
+ ---
597
+
598
+ ### Phase 7 — Build Context Updates
599
+
600
+ Construct the full delta object to pass to context_write:
601
+
602
+ #### 7a — For each service found:
603
+
604
+ If service is NEW (not in context.services):
605
+ - Build full service entry from Phase 2 or Phase 3 scan results
606
+ - Set `sync_origin = "legacy"` if classified as legacy,
607
+ `sync_origin = "agent"` if agent-initialized
608
+ - Increment `services_synced` and `services_new` counters
609
+
610
+ If service is EXISTING (already in context.services):
611
+ - Only update fields that were empty/null in context AND found on disk
612
+ - Never overwrite a populated context value unless user confirmed it
613
+ in Phase 6
614
+ - Record what was filled in for the report
615
+ - Increment `services_synced` counter
616
+
617
+ Fields to sync per NodeJS service:
618
+ - name, port, description, author, package_name
619
+ - client_type, encrypted_transport, supported_languages
620
+ - encryption_key (if found in .env and not already in context)
621
+ - encryption_iv (if found in .env and not already in context)
622
+ - api_key (if found in .env and not already in context)
623
+ - redis_host, redis_port
624
+ - entry_point (actual path if different from app.js)
625
+ - tech_stack.dependencies (full list from package.json)
626
+ - middleware_stack (list of detected middleware types)
627
+ - sync_origin, last_synced_at = ISO now
628
+
629
+ Fields to sync per ReactJS service:
630
+ - name, port, description
631
+ - linked_service, linked_service_port
632
+ - tech_stack.dependencies
633
+ - sync_origin, last_synced_at = ISO now
634
+
635
+ #### 7b — For each route found:
636
+
637
+ If route is NEW (not in context.api_routes):
638
+ - Add to api_routes[] with: service, method, path, version, module
639
+ - Increment `routes_discovered` and `routes_new` counters
640
+
641
+ If route ALREADY in context.api_routes:
642
+ - Increment `routes_discovered` counter only
643
+
644
+ #### 7c — For database:
645
+
646
+ If db.type was empty in context:
647
+ - Set db.type, db.name, db.host, db.port, db.user from scan results
648
+
649
+ For each table found during scan:
650
+ - If NEW → add to context.db.schema.tables with full column list
651
+ Increment `db_tables_new`
652
+ - If EXISTING → merge any new columns found on disk that are not
653
+ in context (may happen if migration was added manually)
654
+ - Increment `db_tables_synced` counter
655
+
656
+ #### 7d — Set top-level context fields:
657
+
658
+ - If `project_name` is empty → set to first service name found
659
+ - If `initialized_at` is empty → set to ISO now
660
+ - Set `last_command` = "sync"
661
+ - Set `last_updated_at` = ISO now
662
+ - Set `last_command_at` = ISO now
663
+
664
+ ---
665
+
666
+ ### Phase 8 — Write Context
667
+
668
+ Call MCP tool `context_write` with:
669
+ - `updates` = full delta object from Phase 7
670
+ - `operation` = "sync"
671
+
672
+ This ALWAYS runs — even if nothing changed.
673
+ context.json is always written at the end of @sync.
674
+
675
+ If context.json did not exist before → this creates it for the first time.
676
+ After context_write succeeds → call `context_clear_scratchpad` for
677
+ any stale `current_*` keys found in Phase 0.
678
+
679
+ ---
680
+
681
+ ### Phase 9 — Drift Detection (Mode A only)
682
+
683
+ This phase only runs when mode = A (agent-initialized project with
684
+ existing context). Skip entirely for Mode B — legacy projects have
685
+ no expected structure to drift from.
686
+
687
+ Drift detection is read-only. Nothing is modified. Findings are
688
+ informational only.
689
+
690
+ For each service in context.services where `sync_origin == "agent"`
691
+ (or sync_origin is absent, meaning it predates this sync versioning):
692
+
693
+ #### Check 1 — route_manager.js middleware order
694
+
695
+ Read: `<service>/modules/v1/route_manager.js`
696
+ Expected: middleware registered in this exact order:
697
+ 1. rateLimiter
698
+ 2. extractLanguage
699
+ 3. validateApiKey
700
+ 4. validateToken
701
+ 5. decryptRequest (only if encrypted_transport == true)
702
+
703
+ How to check:
704
+ Scan all `router.use('/', ...)` lines in order.
705
+ Extract the middleware name from each line.
706
+ Compare the extracted order against the expected order above.
707
+
708
+ Drift conditions:
709
+ - Any middleware is missing → DRIFT: "Missing middleware: [name]"
710
+ - Any middleware appears in wrong position → DRIFT:
711
+ "[name] appears at position [n], expected position [m]"
712
+ - decryptRequest present when encrypted_transport == false → DRIFT:
713
+ "decryptRequest registered but encrypted_transport is false"
714
+ - decryptRequest absent when encrypted_transport == true → DRIFT:
715
+ "decryptRequest missing but encrypted_transport is true"
716
+ - asyncHandler not wrapping any middleware → DRIFT:
717
+ "asyncHandler wrapper missing on [middleware_name]"
718
+
719
+ ---
720
+
721
+ #### Check 2 — encryption.js library consistency
722
+
723
+ Read: `<service>/utilities/encryption.js`
724
+ Expected: imports only the library matching context.services[<n>].client_type
725
+ - client_type == "reactjs" → should import crypto-js, not cryptlib
726
+ - client_type == "app" → should import cryptlib, not crypto-js
727
+
728
+ Drift conditions:
729
+ - File imports cryptlib but context says client_type == "reactjs" →
730
+ DRIFT: "encryption.js uses cryptlib but client_type is reactjs"
731
+ - File imports crypto-js but context says client_type == "app" →
732
+ DRIFT: "encryption.js uses crypto-js but client_type is app"
733
+ - File imports both libraries → DRIFT:
734
+ "encryption.js imports both crypto-js and cryptlib — only one should be active"
735
+ - Neither library found → DRIFT:
736
+ "encryption.js does not import any encryption library"
737
+
738
+ ---
739
+
740
+ #### Check 3 — response.js encrypted_transport flag
741
+
742
+ Read: `<service>/utilities/response.js`
743
+ Expected: reads ENCRYPTED_TRANSPORT from process.env
744
+
745
+ Drift conditions:
746
+ - ENCRYPTED_TRANSPORT not referenced → DRIFT:
747
+ "response.js does not check ENCRYPTED_TRANSPORT — all responses
748
+ may be unencrypted regardless of config"
749
+ - res.json( appears directly → DRIFT:
750
+ "response.js calls res.json() directly — responses bypass the encryption wrapper"
751
+
752
+ ---
753
+
754
+ #### Check 4 — headerValidator.js decryptRequest presence
755
+
756
+ Read: `<service>/middleware/headerValidator.js`
757
+ Expected based on context.services[<n>].encrypted_transport:
758
+ - true → decryptRequest function must be defined and exported
759
+ - false → decryptRequest must NOT be present
760
+
761
+ Drift conditions:
762
+ - Function present but encrypted_transport == false → DRIFT:
763
+ "headerValidator.js defines decryptRequest but encrypted_transport
764
+ is false — dead code"
765
+ - Function absent but encrypted_transport == true → DRIFT:
766
+ "headerValidator.js is missing decryptRequest but encrypted_transport
767
+ is true — request bodies will not be decrypted"
768
+
769
+ ---
770
+
771
+ #### Check 5 — language file key parity
772
+
773
+ Read: all files in `<service>/languages/`
774
+ Expected: every language file has the same set of keys as en.js
775
+
776
+ Drift conditions:
777
+ - Any language file has fewer keys than en.js → DRIFT:
778
+ "[lang].js is missing [n] keys that exist in en.js: [list]"
779
+ - Any language file has extra keys → DRIFT:
780
+ "[lang].js has [n] extra keys not in en.js: [list]"
781
+
1
782
  ---
2
- slash_command: /codeninja:sync
3
- personas: [global-orchestrator, nodejs-backend]
4
- skills: [mcp-and-context]
5
- description: Scan the entire repo and rebuild context.json from disk
783
+
784
+ #### Check 6 — package.json dependencies vs expected
785
+
786
+ Read: `<service>/package.json` dependencies
787
+
788
+ Required packages always:
789
+ express, dotenv, localizify, moment, jsonwebtoken, ioredis,
790
+ nodemailer, firebase-admin, validatorjs, pg-format,
791
+ express-rate-limit, rand-token
792
+
793
+ Required by client_type:
794
+ - reactjs → crypto-js must be present
795
+ - app → cryptlib must be present
796
+
797
+ Required by db_type:
798
+ - postgresql → pg must be present
799
+ - mysql → mysql2 must be present
800
+ - mongodb → mongoose must be present
801
+
802
+ Drift conditions:
803
+ - Required package missing → DRIFT:
804
+ "package.json is missing required dependency: [package_name]"
805
+ - Wrong encryption package present → DRIFT:
806
+ "package.json has [wrong_package] but client_type is [type]"
807
+
6
808
  ---
7
809
 
8
- # /codeninja:sync
810
+ #### Check 7 — model files pattern compliance
9
811
 
10
- Delegates to: `.codeninja/commands/sync.workflow.md`
812
+ For each module in context.services[<n>].modules:
813
+ Read: `<service>/modules/v1/<ModuleName>/<module>_model.js`
11
814
 
12
- ## Before Running
13
- 1. Call `context_read` load current state
14
- 2. Call `service_scan`discover all services on disk
815
+ Drift conditions:
816
+ - express imported DRIFT:
817
+ "[module]_model.js imports expressmodel files must not use Express objects"
818
+ - res.json or res.status found → DRIFT:
819
+ "[module]_model.js calls res.json/res.status directly"
820
+
821
+ ---
822
+
823
+ ## Drift Report Format
824
+
825
+ After all checks complete, append to the sync report:
826
+ ```
827
+ Drift Analysis
828
+ ─────────────────────────────────────────
829
+ Files checked : [n]
830
+ Clean : [n] (no drift detected)
831
+ Drift found : [n] files
832
+ ─────────────────────────────────────────
833
+ [If drift found:]
834
+
835
+ ⚠ DRIFT DETECTED — manual review recommended
836
+
837
+ [service_name]/modules/v1/route_manager.js
838
+ → Missing middleware: decryptRequest
839
+
840
+ [service_name]/utilities/encryption.js
841
+ → encryption.js uses cryptlib but client_type is reactjs
842
+ ─────────────────────────────────────────
843
+ NOTE: Drift is informational only. No files were modified.
844
+ Run @audit for deeper code quality analysis.
845
+ ─────────────────────────────────────────
846
+ ```
847
+
848
+ If no drift found:
849
+ ```
850
+ Drift Analysis : ✓ All [n] files match expected structure
851
+ ```
852
+
853
+ ---
854
+
855
+ ### Phase 10 — Sync Report
856
+
857
+ Display the full sync report.
858
+
859
+ ```
860
+ ┌─────────────────────────────────────────────────┐
861
+ │ @sync Complete │
862
+ └─────────────────────────────────────────────────┘
863
+
864
+ Mode : [Agent Project / Legacy Project]
865
+ ─────────────────────────────────────────────────
866
+ Services scanned : [n] ([x] new, [y] updated, [z] unchanged)
867
+ Routes found : [n] ([x] new to context)
868
+ DB tables found : [n] ([x] new to context)
869
+ Gaps filled : [n]
870
+ Legacy inferences: [n] (values derived from code analysis)
871
+ ─────────────────────────────────────────────────
872
+ [If Mode B or any legacy services found:]
873
+
874
+ ⚙ Legacy Services Detected
875
+ ─────────────────────────────────────────────────
876
+ [service_name] ([tech_type])
877
+ Entry point : [actual entry point file]
878
+ Port : [port or "not found — check manually"]
879
+ Routes found : [n] (from [location(s)])
880
+ DB driver : [driver or "not detected"]
881
+ Encryption : [library or "not detected"]
882
+ client_type : [value or "could not determine — set manually"]
883
+ Languages : [list or "none detected"]
884
+ Middleware : [list of detected types]
885
+ ⚠ Values inferred from code — review and correct if needed
886
+
887
+ [Repeat per legacy service]
888
+ ─────────────────────────────────────────────────
889
+ [If any low-confidence values were inferred:]
890
+
891
+ ⚠ Low-Confidence Values (verify before using)
892
+ [service_name].port = [value] — inferred from [source]
893
+ [service_name].client_type = [value] — inferred from [source]
894
+ [list any others]
895
+ To correct: update context.json directly or re-run @sync
896
+ after adding a .env file with the correct values.
897
+ ─────────────────────────────────────────────────
898
+ [If any misplaced database/ folders found:]
899
+
900
+ ⚠ Misplaced Database Folder
901
+ Found: [path inside service folder]
902
+ Expected: [repo_root]/database/
903
+ Scanned and added to context — consider moving to repo root.
904
+ ─────────────────────────────────────────────────
905
+ [If any port conflicts found:]
906
+
907
+ ⚠ Port Conflicts
908
+ Port [port] is used by both: [service_a] and [service_b]
909
+ Review and update .env files to resolve before starting services.
910
+ ─────────────────────────────────────────────────
911
+ [If any unlinked React frontends:]
912
+
913
+ ⚠ Unlinked Frontend
914
+ [service_name] — no matching backend found for API URL: [url]
915
+ Set context.services.[service_name].linked_service manually
916
+ or re-run @sync after the backend is initialized.
917
+ ─────────────────────────────────────────────────
918
+ [If non-JS projects found:]
919
+
920
+ ℹ Unsupported Tech Detected (recorded only, not parsed)
921
+ [folder_name] — [detected_tech]
922
+ ─────────────────────────────────────────────────
923
+ [If Mode A — drift analysis section:]
924
+
925
+ [Drift report as formatted above]
926
+ ─────────────────────────────────────────────────
927
+ Context updated : .codeninja/context/context.json ✓
928
+ ─────────────────────────────────────────────────
929
+ ```
930
+
931
+ After the report, run task: `show-final-summary`
932
+
933
+ ---
934
+
935
+ ## Inference Confidence Levels
936
+
937
+ When recording legacy-inferred values in context, tag each with:
938
+
939
+ **HIGH** — value read directly from a config file (.env, package.json,
940
+ explicit constant). Treat as fact.
941
+
942
+ **MEDIUM** — value inferred from code patterns (port from `.listen(PORT)`
943
+ where PORT came from a variable, not a literal).
944
+ Usable but should be confirmed.
945
+
946
+ **LOW** — value guessed from folder name, comment, or single ambiguous
947
+ occurrence. Always listed in the sync report. User should confirm.
948
+
949
+ Store as: `context.services[<n>].<field>_confidence = "high"|"medium"|"low"`
950
+
951
+ ---
15
952
 
16
- ## Execution
17
- Read and execute `sync.workflow.md`.
18
- Use `run_drift_check` MCP tool to compare context vs disk.
19
- Surface all detected drifts before writing anything.
20
- User approves the sync before context is updated.
953
+ ## What Sync Never Does
21
954
 
22
- ## After Running
23
- Call `context_write` with fully rebuilt context.
955
+ - Never modifies any source file — read only outside of context.json
956
+ - Never deletes service folders, SQL files, or any project files
957
+ - Never removes existing context entries
958
+ - Never overwrites a HIGH-confidence context value with a MEDIUM or
959
+ LOW inferred value without user confirmation
960
+ - Never assumes a value is correct if two files disagree on it —
961
+ flag the conflict and ask
962
+ - Never silently skips a directory — if it cannot be classified,
963
+ record it as unknown and mention it in the report
964
+ - Never runs drift detection on legacy services — only agent-initialized