forked from jsbattig/code-indexer
-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathCLAUDE.md.old
More file actions
1215 lines (878 loc) · 41.1 KB
/
CLAUDE.md.old
File metadata and controls
1215 lines (878 loc) · 41.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
# Code-Indexer (CIDX) Project Instructions
## 0. DOCUMENTATION STANDARDS
**NO EMOJI/ICONOGRAPHY**: Never use emoji, unicode icons, or decorative symbols in any documentation files (README.md, CLAUDE.md, CHANGELOG.md, docs/*.md). Use plain text headers and formatting only. This applies to all project documentation.
**Examples of forbidden iconography:**
- Emoji: 🔍 🕰️ ⚡ 🎯 🔄 🤖 ✅ ❌ 👍 🚀 🔧 🔐
- Unicode symbols: ✓ ✗ ★ ● ◆ → ←
- Decorative characters
**Correct heading format**: Use plain text only
```markdown
### Performance Improvements
### Git History Search
```
---
## CRITICAL: SSH CONNECTION POLICY
**ABSOLUTE PROHIBITION**: NEVER use `ssh` command directly via Bash tool.
**MANDATORY**: ALWAYS use MCP SSH server tools for ALL remote connections:
- `mcp__ssh__ssh_connect` - Establish SSH connection
- `mcp__ssh__ssh_exec` - Execute commands on remote server
- `mcp__ssh__ssh_disconnect` - Close SSH connection
- `mcp__ssh__ssh_upload_file` - Upload files via SFTP
- `mcp__ssh__ssh_download_file` - Download files via SFTP
**WHY**: Direct `ssh` command causes authentication failures. MCP SSH server provides proper connection management.
**VIOLATION = FUNDAMENTAL FAILURE**: Using direct `ssh` command breaks remote operations.
---
## CRITICAL: LOCAL TESTING BEFORE DEPLOYMENT
**ABSOLUTE PROHIBITION**: NEVER deploy to or test on the production CIDX server until work is approved.
**MANDATORY WORKFLOW**:
1. **ALL development and testing happens LOCALLY** on the development machine
2. CIDX server runs locally at localhost:8000
3. For callbacks, use the development machine's external IP (reachable from Claude Server)
4. The development machine and Claude Server can see each other - use this for E2E testing
5. The production server is in a special firewalled network area - DO NOT TOUCH
**DEPLOYMENT ONLY WHEN**:
- User explicitly approves the work
- User tells you to "commit and push to master" (triggers auto-deployment), OR
- User tells you to "deploy manually to production server"
**WHY**: The production server is production. Test everything locally first with full E2E validation before any deployment.
**VIOLATION = FUNDAMENTAL FAILURE**: Touching production server without explicit user approval breaks the development workflow.
---
## CRITICAL: ADMIN PASSWORD - NEVER CHANGE
**ABSOLUTE PROHIBITION**: NEVER change the admin user password during local development or testing.
**DEFAULT CREDENTIALS** (localhost:8000):
- Username: `admin`
- Password: `admin`
**WHY**: The admin/admin credentials are the standard for local development. Changing them breaks manual testing workflows and causes "session_expired" login failures that are difficult to debug.
**IF YOU BROKE IT** (login returns "session_expired" with correct credentials):
```bash
# Generate new hash for 'admin' password
python3 -c "
from src.code_indexer.server.auth.password_manager import PasswordManager
pm = PasswordManager()
print(pm.hash_password('admin'))
"
# Update database with new hash (replace HASH with output above)
sqlite3 ~/.cidx-server/data/cidx_server.db "UPDATE users SET password_hash='HASH' WHERE username='admin';"
```
**VIOLATION = WASTED TIME**: Changing admin password causes login failures that require database surgery to fix.
**RECORDED**: 2026-01-26 - After admin password was changed causing "session_expired" errors on localhost:8000 login.
---
## SSH SERVER RESTART - CRITICAL PROCEDURE
**ABSOLUTE PROHIBITION**: NEVER use `kill -15 && nohup python3 -m ... &` for server restarts.
**WHY**: Manual process management with nohup causes SSH session lockups. You MUST use systemd service management.
**CORRECT PROCEDURE** for cidx-server restarts:
```bash
# Connect via MCP SSH tools
mcp__ssh__ssh_connect(...)
# Restart using systemd
echo "PASSWORD" | sudo -S systemctl restart cidx-server
# Verify service status
systemctl status cidx-server --no-pager
```
**VIOLATION = SSH LOCKUP**: Using manual kill/nohup will freeze the SSH session indefinitely, requiring session termination and reconnection.
**RECORDED**: 2025-11-29 - After multiple instances of SSH lockups caused by manual process management instead of systemd service control.
---
## CRITICAL: AUTO-UPDATER IDEMPOTENT DEPLOYMENT - MANDATORY
**ABSOLUTE PROHIBITION**: NEVER implement server environment changes that require manual intervention on production servers.
**MANDATORY APPROACH**: ALL changes to systemd service files, environment variables, or server configuration MUST be implemented through the auto-updater in an idempotent fashion.
**WHY**: Production servers use the auto-updater workflow:
1. `git pull` - gets new code
2. `pip install` - installs new code
3. `DeploymentExecutor.execute()` - runs idempotent configuration updates
4. `systemctl restart` - restarts with new code AND new config
The auto-updater is the ONLY mechanism that touches production servers. If you add a new environment variable, service file change, or configuration requirement, the auto-updater MUST handle it automatically.
**IMPLEMENTATION PATTERN** (see `deployment_executor.py`):
```python
# Add idempotent method like _ensure_workers_config() or _ensure_cidx_repo_root()
def _ensure_new_config(self) -> bool:
"""Idempotently ensure new configuration is present."""
# 1. Check if already configured - return True if so
# 2. If not, add the configuration
# 3. Run sudo systemctl daemon-reload
# 4. Return True on success, False on error
# Call it in execute() method
def execute(self) -> bool:
# ... git pull, pip install ...
self._ensure_workers_config()
self._ensure_cidx_repo_root()
self._ensure_new_config() # ADD YOUR NEW CONFIG HERE
```
**EXAMPLES**:
- Adding `CIDX_REPO_ROOT` env var: Added `_ensure_cidx_repo_root()` to auto-updater
- Adding `--workers 1` flag: Added `_ensure_workers_config()` to auto-updater
- Adding new systemd setting: Add new `_ensure_*()` method to auto-updater
**VIOLATION = BROKEN PRODUCTION**: Expecting manual server intervention means the fix will NEVER reach production servers that rely on auto-update.
**RECORDED**: 2026-01-30 - Bug #87 fix required adding CIDX_REPO_ROOT to auto-updater because production servers don't re-run deploy-server.sh.
---
## CIDX SERVER PORT CONFIGURATION - DO NOT CHANGE
**ABSOLUTE PROHIBITION**: NEVER change the port configuration for cidx-server, HAProxy, or firewall.
**LOCKED CONFIGURATION** (verified working 2025-11-30):
- cidx-server systemd service: port 8000
- HAProxy backend: forwards to production server on port 8000
- Firewall: allows port 8000 from HAProxy server
**WHY**: These three components must be synchronized. Changing any one breaks external HTTPS access.
**VIOLATION = SERVER INACCESSIBLE**: Any port change will cause HAProxy 503 errors.
**RECORDED**: 2025-11-30 - After port mismatch caused HAProxy backend failure.
---
## SCIP INDEX FILE LIFECYCLE - CRITICAL KNOWLEDGE
**SCIP files are DELETED after database conversion.**
When `cidx scip generate` runs:
1. Language indexer (scip-dotnet, scip-python, etc.) creates `index.scip` (protobuf format)
2. CIDX converts `index.scip` to `index.scip.db` (SQLite database)
3. Original `index.scip` file is **DELETED** after successful conversion
**NEVER look for .scip files** - they don't exist after generation completes. Only `.scip.db` files remain.
**Query commands work with .scip.db files**, not raw .scip protobuf files.
**RECORDED**: 2025-12-21 - After repeatedly searching for non-existent .scip files during C# SCIP indexer testing.
---
## CIDX SERVER CONFIGURATION - NO ENVIRONMENT VARIABLES
**ABSOLUTE PROHIBITION**: NEVER use environment variables to store settings, configuration, or state within the CIDX server context.
**This is NOT negotiable. This is NOT a suggestion. This is a hard rule.**
**WHY**: Environment variables are:
- Invisible and hard to debug
- Not persisted properly across restarts
- Inconsistent between development and production
- A source of repeated configuration failures in this project
**CIDX SERVER HAS A DEDICATED CONFIGURATION SYSTEM**:
The CIDX server uses a **Web UI Configuration Screen** for all settings. This is the single source of truth for server configuration.
**MANDATORY**: When adding ANY new configurable setting to CIDX server:
1. Add it to the Web UI Configuration Screen
2. Store it in the server's configuration persistence layer
3. Access it through the configuration API
4. NEVER use environment variables as a shortcut
**CORRECT APPROACHES** for CIDX server configuration:
1. **Web UI Config Screen** (PRIMARY - use this for all new settings)
2. Configuration files (JSON, YAML, TOML)
3. Command-line arguments (for startup options only)
4. In-memory configuration objects passed explicitly
**WRONG APPROACH** (NEVER DO THIS):
```python
# WRONG - NEVER DO THIS
import os
os.environ["CIDX_SETTING"] = "value"
setting = os.getenv("CIDX_SETTING")
```
**RIGHT APPROACH**:
```python
# RIGHT - Use the server's configuration system
from code_indexer.server.config import get_config
config = get_config()
setting = config.some_setting
```
**VIOLATION = IMMEDIATE REJECTION**: Any code review that introduces environment variable usage for CIDX server settings MUST be rejected and rewritten.
**RECORDED**: 2025-01-14 - After repeated failures caused by environment variable-based configuration.
---
## CRITICAL: TESTING WORKFLOW GOLDEN RULES
**ABSOLUTE PROHIBITION**: NEVER run fast-automation.sh after every small change. That's idiotic and wastes time.
**THE CORRECT WORKFLOW**:
1. **During development - TARGETED TESTS ONLY**:
- Change `base_client.py` -> run `pytest tests/unit/api_clients/test_base_*.py -v --tb=short`
- Change `auth_client.py` -> run `pytest tests/unit/api_clients/test_auth_*.py -v --tb=short`
- Change `handlers.py` -> run `pytest tests/unit/server/mcp/test_handlers*.py -v --tb=short`
- Targeted tests give fast feedback (seconds, not minutes)
2. **fast-automation.sh - FINAL GATE ONLY**:
- Run ONLY after ALL changes are complete
- This is the final validation before marking work done
- Use 600000ms (10 minute) timeout: `./fast-automation.sh` with Bash timeout parameter
**WHY THIS MATTERS**:
- Targeted tests: seconds of feedback
- fast-automation.sh: 6-7 minutes for 865+ tests
- Running fast-automation after every change = hours wasted waiting
**TESTING HIERARCHY**:
```
1. Targeted unit tests (FAST - seconds)
|
v
2. Manual testing (verify feature works)
|
v
3. fast-automation.sh (FINAL GATE - must pass before done)
```
**VIOLATION = WASTED TIME**: Running full test suite during iterative development is a fundamental workflow failure.
**RECORDED**: 2026-01-27 - Established as golden rule after repeated time waste from running full suite during development.
---
## CRITICAL: fast-automation.sh EXECUTION PROCEDURE
**THIS IS NOT OPTIONAL. THIS IS THE LAW.**
### The Goal
**Clean fast-automation.sh run**: Zero failures, completes in under 10 minutes.
If this goal is not met, you MUST fix the problem before considering work complete.
### Step-by-Step Execution Procedure
**STEP 1: Launch with Hard Timeout**
```bash
# MANDATORY: Use 600000ms (10 minute) timeout parameter in Bash tool
./fast-automation.sh
```
The Bash tool timeout parameter is the HARD KILL mechanism. When 10 minutes hits, the process dies.
**STEP 2: Capture Output**
The output MUST contain:
- Test results (passed/failed counts)
- `--durations` telemetry (slowest tests) - fast-automation.sh should include this
- Any failure tracebacks
**STEP 3: Analyze Results**
Three possible outcomes:
| Outcome | What Happened | Required Action |
|---------|---------------|-----------------|
| **SUCCESS** | Completed <10min, zero failures | DONE. Work is complete. |
| **TIMEOUT** | Hit 10 minute limit, killed | Go to TIMEOUT REMEDIATION |
| **FAILURES** | Completed but tests failed | Go to FAILURE REMEDIATION |
### TIMEOUT REMEDIATION (Mandatory Procedure)
**ABSOLUTE PROHIBITION**: NEVER "continue monitoring" after timeout. The process is DEAD. Fix the problem.
**Step T1**: Extract slowest tests from output
- Look for `--durations` section showing slowest tests
- If not visible, run: `pytest tests/ --durations=20 --collect-only -q` to identify slow tests
**Step T2**: Identify tests exceeding thresholds
- Tests >30 seconds: MUST be excluded from fast-automation.sh
- Tests >10 seconds: SHOULD be optimized or excluded
- Tests >5 seconds: Note for potential optimization
**Step T3**: Fix or exclude slow tests
Option A - Optimize the test:
```python
# Before: Slow test doing unnecessary work
def test_something():
expensive_setup() # Remove if not needed
...
# After: Optimized
@pytest.fixture(scope="module") # Cache expensive setup
def cached_setup():
return expensive_setup()
def test_something(cached_setup):
...
```
Option B - Mark as slow and exclude:
```python
@pytest.mark.slow
def test_inherently_slow_operation():
...
```
Ensure fast-automation.sh excludes slow tests:
```bash
pytest tests/ -m "not slow" --durations=20
```
**Step T4**: Re-run fast-automation.sh
- Same 10-minute hard timeout
- Repeat until SUCCESS outcome
### FAILURE REMEDIATION (Mandatory Procedure)
**Step F1**: Identify all failing tests from output
**Step F2**: Fix each failure
- Read the test code
- Read the code being tested
- Understand what broke
- Fix the root cause (not symptoms)
**Step F3**: Run targeted tests to verify fix
```bash
pytest tests/path/to/failing_test.py -v --tb=short
```
**Step F4**: Re-run fast-automation.sh
- Same 10-minute hard timeout
- Repeat until SUCCESS outcome
### Performance Standards
| Metric | Target | Action Threshold | Exclusion Threshold |
|--------|--------|------------------|---------------------|
| Individual test | <5 seconds | >10 seconds: investigate | >30 seconds: exclude |
| Total suite | <10 minutes | >10 minutes: HARD KILL | N/A |
### Red Flags Requiring Immediate Investigation
- fast-automation.sh exceeds 10 minutes (HARD KILL, fix immediately)
- Any single test exceeds 30 seconds (exclude from fast suite)
- Test failures on code you didn't touch (regression - investigate)
- Flaky tests (pass sometimes, fail sometimes) - fix or exclude
### What "Continue Monitoring" Actually Means
**IT MEANS NOTHING. THERE IS NO SUCH THING.**
- Process hit 10 minutes? It's DEAD. Fix the problem.
- Process still running at 10 minutes? KILL IT. The timeout should have done this.
- Want to "see if it finishes"? NO. 10 minutes is the law.
**VIOLATION = FUNDAMENTAL FAILURE**: Allowing fast-automation.sh to run beyond 10 minutes violates the core testing workflow. There are no exceptions.
**RECORDED**: 2026-01-28 - After "continue monitoring" anti-pattern wasted time instead of fixing slow tests.
---
## GIT BRANCHING AND DEPLOYMENT STRATEGY
### Branch Structure
**Three-tier branching model**:
- `development` - Active development branch, all work happens here
- `staging` - Staging environment branch, receives merges from development
- `master` - Production branch, receives merges from staging
**Key Principles**:
- ALL code changes and version bumps happen in `development` branch ONLY
- `staging` and `master` are merge-only branches (no direct commits)
- Version tags automatically trigger environment deployments
### Auto-Deployment Strategy
**Deployment triggers** - Version tags on specific branches trigger automatic deployment:
| Branch | Tag Presence | Deployment Target | Server |
|--------|--------------|-------------------|--------|
| `master` | v8.x.x tag | Production environment | .30 server |
| `staging` | v8.x.x tag | Staging environment | .20 server |
| `development` | Any state | No auto-deployment | localhost only |
**How it works**:
- When you push a commit with a version tag to `staging` branch → .20 server auto-deploys
- When you push a commit with a version tag to `master` branch → .30 server auto-deploys
- Tags automatically transfer with commits during merge operations (Git behavior)
### "Deploy to Staging" Workflow
When user says **"deploy to staging"**, execute this workflow:
**Step 1: Ensure version tag exists in development**
```bash
# Check if development HEAD has version tag
git checkout development
git describe --exact-match HEAD 2>/dev/null
# If no tag found:
# - Bump version in development (__init__.py, CHANGELOG.md, README.md)
# - Commit: "chore: bump version to X.Y.Z"
# - Create tag: git tag vX.Y.Z
# - Push: git push origin development --tags
```
**Step 2: Merge development to staging**
```bash
git checkout staging
git merge development
# Version tag automatically transfers with the merge commit
```
**Step 3: Push staging (triggers auto-deployment)**
```bash
git push origin staging
# Tag is already present from merge, triggers .20 server deployment
```
**Key Notes**:
- If development HEAD doesn't have a tag, you MUST bump version first
- Never make code changes directly in staging branch
- Tags automatically transfer during merge (no manual re-tagging needed)
### "Deploy to Production" Workflow
When user says **"deploy to production"**, execute this workflow:
**Step 1: Ensure staging HEAD has version tag**
```bash
# Check if staging HEAD has version tag
git checkout staging
git describe --exact-match HEAD 2>/dev/null
# If no tag found:
# - This means you forgot to deploy to staging properly
# - Go back to development, bump version, deploy to staging first
# - NEVER bump version directly in staging
```
**Step 2: Merge staging to master**
```bash
git checkout master
git merge staging
# Version tag automatically transfers with the merge commit
```
**Step 3: Push master (triggers auto-deployment)**
```bash
git push origin master
# Tag is already present from merge, triggers .30 server deployment
```
**Key Notes**:
- Production deployment ALWAYS goes through staging first
- If staging doesn't have a tag, go back to development and fix the workflow
- Never make code changes directly in master branch
- Tags automatically transfer during merge (no manual re-tagging needed)
### Branch Verification Before Development (MANDATORY CHECK)
**CRITICAL SAFETY CHECK**: Before starting ANY development work, verify you're in the correct branch.
**Pre-Development Checklist**:
```bash
# Check current branch
git branch --show-current
```
**Required Branches for Development**:
- `development` - Main development branch (default for all work)
- `feature/*` - Feature branches (created from development)
- `bugfix/*` - Bug fix branches (created from development)
**WRONG Branches for Development**:
- `staging` - Merge-only branch, NO direct commits
- `master` - Merge-only branch, NO direct commits
**Workflow When Not in Development Branch**:
1. If in `staging` or `master`: STOP immediately
2. Ask user: "Currently in [branch]. Do you want to develop in staging/master, or should I switch to development branch?"
3. Wait for explicit user confirmation before proceeding
4. If user confirms developing in staging/master: Proceed with WARNING logged
5. If user wants development branch: Switch to development first
**Example Interaction**:
```
Assistant: I notice we're currently in the 'staging' branch. Development work should
happen in the 'development' branch (or feature branch).
Should I:
A) Switch to development branch (recommended)
B) Continue developing in staging branch (not recommended)
Please confirm your choice.
```
**VIOLATION = BROKEN WORKFLOW**: Making direct commits to staging/master bypasses the merge-based deployment workflow and causes branch divergence.
### Version Management Rules
**ABSOLUTE REQUIREMENTS**:
- Version bumps ONLY happen in `development` branch
- Version consists of: `__init__.py`, `CHANGELOG.md`, `README.md` updates + git tag
- Format: `vX.Y.Z` (e.g., `v8.8.18`)
- Every deployment MUST have a version tag
**Workflow Summary**:
```
development (bump version, create tag)
↓ merge
staging (tag transfers automatically, push triggers .20 deployment)
↓ merge
master (tag transfers automatically, push triggers .30 deployment)
```
**VIOLATION = BROKEN DEPLOYMENT**: Skipping version tags or making direct commits to staging/master breaks the auto-deployment workflow.
**RECORDED**: 2026-02-01 - Established three-tier branching strategy with tag-based auto-deployment.
---
## 1. CRITICAL BUSINESS INSIGHT - Query is Everything
**THE SINGLE MOST IMPORTANT FEATURE**: Query capability is the core value proposition of CIDX. All query features available in CLI MUST be available in MCP/REST APIs with full parity.
**Query Parity is Non-Negotiable**: Any feature gap between CLI and MCP/REST query interfaces represents a critical degradation of the product's primary function. This is not optional - this is the business.
**Current Status** (as of 2025-11-18):
- CLI query parameters: 23 total
- MCP query parameters: 11 total (48% parity)
- **P0 filters implemented**: language, exclude_language, path_filter, exclude_path, file_extensions, accuracy
- **Remaining gap**: FTS-specific options (8 params), temporal options (4 params)
**Never remove or break query functionality** without explicit approval. Query degradation = product failure.
---
## 2. Operational Modes Overview
CIDX has **two operational modes** (simplified from three in v7.x). Understanding which mode you're working in is critical.
### Mode 1: CLI Mode (Direct, Local)
**What**: Direct command-line tool for local semantic code search
**Storage**: FilesystemVectorStore in `.code-indexer/index/` (container-free)
**Use Case**: Individual developers, single-user workflows
**Commands**: `cidx init`, `cidx index`, `cidx query`
**Characteristics**:
- Indexes code locally in project directory
- No daemon, no server, no network
- Vectors stored as JSON files on filesystem
- Each query loads indexes from disk
- Container-free, instant setup
### Mode 2: Daemon Mode (Local, Cached)
**What**: Local RPyC-based background service for faster queries
**Storage**: Same FilesystemVectorStore + in-memory cache
**Use Case**: Developers wanting faster repeated queries and watch mode
**Commands**: `cidx config --daemon`, `cidx start`, `cidx watch`
**Characteristics**:
- Caches HNSW/FTS indexes in memory (daemon process)
- Auto-starts on first query when enabled
- Unix socket communication (`.code-indexer/daemon.sock`)
- Faster queries (~5ms cached vs ~1s from disk)
- Watch mode for real-time file change indexing
- Container-free, runs as local process
---
## 3. Architecture Details
**For Full Details**: See `/docs/v5.0.0-architecture-summary.md` and `/docs/v7.2.0-architecture-incremental-updates.md`
### Vector Storage (All Modes)
**Current Architecture**: **FilesystemVectorStore** - Container-free, filesystem-based (only backend in v8.0+)
**Key Points**:
- Vectors as JSON files in `.code-indexer/index/{collection}/`
- Quantization: Model dims (1024/1536) → 64-dim → 2-bit → filesystem path
- Git-aware: Blob hashes (clean files), text content (dirty files)
- Performance: <1s query, <20ms incremental HNSW updates
- Thread-safe with atomic writes
- Supports VoyageAI embedding dimensions (1024 for voyage-3, 1536 for voyage-3-large)
### Key Architecture Topics (See Docs)
**From `/docs/v7.2.0-architecture-incremental-updates.md`**:
- Incremental HNSW updates (All Modes)
- Change tracking system
- Real-time vs batch updates
- Performance optimizations
**From `/docs/architecture.md`**:
- Filesystem vector storage architecture
- HNSW graph-based indexing
- Git-aware storage strategies
- Query performance optimization
---
## 4. Daily Development Workflows
### Test Suites
- **fast-automation.sh**: 865+ tests, ~6-7min - Run from Claude, MUST stay fast
- **server-fast-automation.sh**: Server-specific tests
- **GitHub Actions CI**: ~814 tests, restricted environment
- **full-automation.sh**: Complete suite, 10+ min - Ask user to run
**Critical**: Use **600000ms (10 min) timeout** for fast-automation.sh, **1200000ms (20 min) timeout** for full-automation.sh
**Testing Principles**:
- Tests don't clean state (performance optimization)
- Container-free architecture (instant setup, no overhead)
- E2E tests use `cidx` CLI directly
- Slow tests excluded from fast suites
**MANDATORY Testing Workflow Order**:
1. **Targeted Unit Tests FIRST**: Write and run specific unit tests for the functionality being added/fixed/modified
2. **Manual Testing SECOND**: Execute manual testing to verify the functionality works end-to-end
3. **fast-automation.sh LAST**: Run full regression suite as FINAL validation before marking work complete
**Why This Order**:
- fast-automation.sh takes 6-7 minutes - too slow for rapid feedback loops
- Targeted unit tests provide immediate feedback (seconds, not minutes)
- Manual testing validates real-world behavior before committing to full suite
- fast-automation.sh is the FINAL gate, not a development tool
**ABSOLUTE PROHIBITION**: NEVER run fast-automation.sh as part of iterative development. Use it ONLY as final validation after unit tests pass and manual testing confirms functionality works.
**Definition of Done**: Feature complete when fast-automation.sh passes fully (after targeted unit tests pass AND manual testing confirms functionality)
### Test Performance Management (MANDATORY)
**ABSOLUTE PROHIBITION**: NEVER introduce slow-running tests to fast-automation.sh without explicit justification.
**Performance Standards**:
- **Individual test target**: <5 seconds per test
- **Suite total target**: <3 minutes for 865+ tests
- **Action threshold**: Any test >10 seconds requires investigation
- **Exclusion threshold**: Tests >30 seconds move to full-automation.sh
**Timing Telemetry (MANDATORY)**:
Every fast-automation.sh execution MUST collect and analyze timing data:
```bash
# Run with timing telemetry
pytest tests/ --durations=20 --tb=short -v
# Or use pytest-benchmark for detailed metrics
pytest tests/ --benchmark-only --benchmark-autosave
```
**Post-Execution Analysis Workflow**:
1. Review `--durations=20` output (20 slowest tests)
2. Identify any tests >5 seconds
3. For slow tests, determine root cause:
- Unnecessary I/O operations
- Missing test fixtures/caching
- Inefficient setup/teardown
- Actual feature complexity (inherent slowness)
4. Take action based on cause:
- **Fixable**: Optimize the test (cache fixtures, reduce I/O, parallelize)
- **Inherent slowness**: Move to full-automation.sh ignore list
- **Borderline**: Add `@pytest.mark.slow` decorator for conditional execution
**Slow Test Ignore List**:
Maintain explicit ignore list in `pytest.ini` or `pyproject.toml`:
```toml
[tool.pytest.ini_options]
markers = [
"slow: marks tests as slow (deselected by fast-automation.sh)",
"integration: marks integration tests (may be slow)",
]
```
**fast-automation.sh MUST exclude slow tests**:
```bash
pytest tests/ -m "not slow" --durations=20
```
**Monitoring Commands**:
```bash
# Identify slow tests
pytest tests/ --durations=0 | grep "s call" | sort -rn -k1
# Benchmark specific test
pytest tests/path/to/test.py::test_name --durations=0 -v
# Profile test execution
pytest tests/ --profile --profile-svg
```
**When Adding New Tests**:
1. Run test individually with `--durations=0`
2. If >5 seconds, investigate optimization opportunities FIRST
3. If inherently slow (>30s), mark with `@pytest.mark.slow` and add to full-automation.sh
4. Document why test is slow in test docstring
5. Verify fast-automation.sh total time doesn't exceed 3 minutes
**Red Flags Requiring Immediate Investigation**:
- fast-automation.sh exceeds 3 minutes total
- Any single test exceeds 10 seconds
- Test duration increases >20% without feature changes
- Timing variance >50% between runs (flaky performance)
### Linting & Quality
**Linting**: Run `./lint.sh` (ruff, black, mypy) after significant changes
**GitHub Actions Monitoring** (MANDATORY):
```bash
git push
gh run list --limit 5
gh run view <run-id> --log-failed # If failed
ruff check --fix src/ tests/ # Fix linting
```
**Zero Tolerance**: Never leave GitHub Actions in failed state. Fix within same session.
### Python Compatibility
**CRITICAL**: Always use `python3 -m pip install --break-system-packages` (never bare `pip`)
### Documentation Updates
**After Feature Implementation**:
1. Run `./lint.sh`
2. Verify README.md accuracy
3. Verify `--help` matches implementation
4. Fix errors, second verification run
### Version Bump Checklist (MANDATORY - ALL FILES)
**CRITICAL**: When bumping the version, ALL of the following files MUST be updated together. Missing any file causes version inconsistency.
**Primary Source of Truth**:
```
src/code_indexer/__init__.py:9 # __version__ = "X.Y.Z" (pyproject.toml reads from here dynamically)
```
**Documentation Files (MUST UPDATE)**:
```
README.md:5 # Version badge in header
CHANGELOG.md # Add new version entry at top (## [X.Y.Z] - YYYY-MM-DD)
docs/architecture.md:301 # Server response example showing version
docs/query-guide.md:739 # Verification scope version reference
docs/query-guide.md:883 # Version Reference line
```
**Example Documentation (CHECK FOR OUTDATED VERSIONS)**:
```
docs/mcpb/setup.md # Example JSON responses may show old versions
docs/server-deployment.md # Example configurations may show old versions
```
**Files that have SEPARATE versions (DO NOT CHANGE for CIDX version bump)**:
```
src/code_indexer/mcpb/__init__.py # MCPB has its own version (1.0.0), independent of CIDX
src/code_indexer/server/app.py # FastAPI OpenAPI spec version, not CIDX version
test-fixtures/ # Test fixture versions are test data, not release versions
```
**Version Bump Command Sequence**:
```bash
# 1. Update primary source
# Edit src/code_indexer/__init__.py - change __version__
# 2. Update documentation
# Edit README.md, CHANGELOG.md, docs/architecture.md, docs/query-guide.md
# 3. Search for any remaining old version references
grep -r "OLD_VERSION" --include="*.md" --include="*.py" .
# 4. Verify
python3 -c "from src.code_indexer import __version__; print(__version__)"
```
**VIOLATION = INCONSISTENT STATE**: Updating only some files creates version mismatch between CLI (`cidx --version`), server responses, and documentation.
---
## 5. Critical Rules (NEVER BREAK)
### Performance Prohibitions
⚠️ **NEVER add `time.sleep()` to production code** for UI visibility. Fix display logic, not processing logic.
### Progress Reporting (EXTREMELY DELICATE)
**Pattern**:
- Setup: `progress_callback(0, 0, Path(""), info="Setup")` → ℹ️ scrolling
- Progress: `progress_callback(current, total, file, info="X/Y files...")` → progress bar
**Rules**:
- Single line at bottom with progress bar + metrics
- NO scrolling console feedback EVER
- DO NOT CHANGE without understanding `cli.py` progress_callback
- Ask confirmation before ANY changes
- Files with progress: BranchAwareIndexer, SmartIndexer, HighThroughputProcessor
### Git-Awareness (CORE FEATURE)
**NEVER remove** these capabilities:
- Git-awareness aspects
- Branch processing optimization
- Relationship tracking
- Deduplication of indexing
This makes CIDX unique. If refactoring removes this, **STOP IMMEDIATELY**.
### Smart Indexer Consistency
When working on smart indexer, always consider `--reconcile` (non git-aware) and maintain feature parity.
### Configuration
- **Temporary Files**: Use `~/.tmp` (NOT `/tmp`)
- **Container-free**: No ports, no containers, instant setup
---
## 6. Performance & Optimization
### FTS Lazy Import (CRITICAL)
⚠️ **NEVER import Tantivy/FTS at module level** in files imported during CLI startup
**Correct Pattern**:
```python
from __future__ import annotations
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from .tantivy_index_manager import TantivyIndexManager
# Inside method where FTS used:
if enable_fts:
from .tantivy_index_manager import TantivyIndexManager
fts_manager = TantivyIndexManager(fts_index_dir)
```
**Why**: Keeps `cidx --help` fast (~1.3s vs 2-3s)
**Verify**: `python3 -c "import sys; from src.code_indexer.cli import cli; print('tantivy' in sys.modules)"` → `False`
### Import Optimization Status
**Completed**:
- voyageai library: 440-630ms → 0ms (eliminated)
- CLI lazy loading: 736ms → 329ms
**Current**: 329ms startup (acceptable, further optimization questionable ROI)
---
## 7. Embedding Provider
### VoyageAI (ONLY PROVIDER)
**ONLY supported provider in v8.0+** - Focus EXCLUSIVELY on VoyageAI
**Token Counting**:
- Use `embedded_voyage_tokenizer.py`, NOT voyageai library
- Critical for 120,000 token/batch API limit
- Lazy imports, caches per model (0.03ms)
- 100% identical to `voyageai.Client.count_tokens()`
- **DO NOT remove/replace** without extensive testing
**Batch Processing**:
- 120,000 token limit per batch enforced
- Automatic token-aware batching
- Transparent batch splitting
**Models**:
- **voyage-3** (default): 1024-dimensional embeddings, best balance of quality and speed
- **voyage-3-large**: 1536-dimensional embeddings, highest quality
---
## 8. CIDX Usage Quick Reference
### CLI Mode (Most Common)
```bash
cidx init # Create .code-indexer/
cidx index # Index codebase
cidx query "authentication" --quiet # Semantic search
cidx query "def.*" --fts --regex # FTS/regex search
```
**Key Flags** (ALWAYS use `--quiet`):
- `--limit N` - Results (default 10, start with 5-10 to conserve context window)
- `--language python` - Filter by language
- `--path-filter */tests/*` - Path pattern
- `--min-score 0.8` - Similarity threshold
- `--accuracy high` - Higher precision
- `--quiet` - Minimal output
**Context Conservation**: Start with low `--limit` values (5-10) on initial queries. High limits consume context window rapidly when results contain large code files.
**Search Decision**:
- ✅ "What code does", "Where is X implemented" → CIDX
- ❌ Exact strings (variable names, config) → grep/find
### Daemon Mode (Optional, Faster)
```bash
cidx config --daemon # Enable daemon
cidx start # Start daemon (auto-starts on first query)
cidx query "..." # Uses cached indexes
cidx watch # Real-time indexing
cidx watch-stop # Stop watch
cidx stop # Stop daemon
```
---
## 9. Mode-Specific Concepts
### CLI Mode Concepts
- `.code-indexer/` - Project config and index storage
- FilesystemVectorStore - Vector storage
- Direct disk I/O per query
- Container-free, instant setup
### Daemon Mode Concepts
- RPyC service on Unix socket
- In-memory HNSW/FTS cache
- Watch mode for real-time updates
- `.code-indexer/daemon.sock`
- Container-free, runs as local process
---
## 10. Miscellaneous
### Local Testing and Deployment
**Configuration File**: `.local-testing` (gitignored)
Contains sensitive deployment information for test environments: