From d3cf38871b68683d451d77797b70e9d51b67dfbc Mon Sep 17 00:00:00 2001 From: M9nx Date: Wed, 22 Jul 2026 09:11:02 +0300 Subject: [PATCH 1/3] chore: preserve audit tooling and dependency updates - Mypy development dependency added - Safe npm audit lockfile refresh - uv.lock intentionally deferred to Release 2 - No application source changes --- pyproject.toml | 5 +++ vscode-extension/package-lock.json | 62 +++++++++++++++++------------- 2 files changed, 41 insertions(+), 26 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index d24a31d..5e66489 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -110,3 +110,8 @@ omit = ["semantic_code_intelligence/tests/*"] fail_under = 70 show_missing = true skip_covered = true + +[dependency-groups] +dev = [ + "mypy>=2.3.0", +] diff --git a/vscode-extension/package-lock.json b/vscode-extension/package-lock.json index 3955eee..0b8d166 100644 --- a/vscode-extension/package-lock.json +++ b/vscode-extension/package-lock.json @@ -1,12 +1,12 @@ { "name": "codexa", - "version": "0.1.0", + "version": "0.2.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "codexa", - "version": "0.1.0", + "version": "0.2.0", "license": "MIT", "devDependencies": { "@types/node": "^20.0.0", @@ -74,9 +74,9 @@ } }, "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "version": "1.1.16", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.16.tgz", + "integrity": "sha512-IDw48K2/2kRkg9LdJxurvq3lV3aBgq0REY89duEqFRthjlPdXHKMj7EnQOXVckxzgisinf3nHfrcE2FufFLXMw==", "dev": true, "license": "MIT", "dependencies": { @@ -124,9 +124,9 @@ } }, "node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "version": "1.1.16", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.16.tgz", + "integrity": "sha512-IDw48K2/2kRkg9LdJxurvq3lV3aBgq0REY89duEqFRthjlPdXHKMj7EnQOXVckxzgisinf3nHfrcE2FufFLXMw==", "dev": true, "license": "MIT", "dependencies": { @@ -534,9 +534,9 @@ "license": "MIT" }, "node_modules/brace-expansion": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.2.tgz", + "integrity": "sha512-w5JZcKgdhDOgOwm8H+KgbosopHMuGcl6qbulwjtz3SM7I7P3yW1eAjzMPLrIE+NQ9vjgANKHWeMHnrT0OXW1oA==", "dev": true, "license": "MIT", "dependencies": { @@ -777,9 +777,9 @@ } }, "node_modules/eslint/node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "version": "1.1.16", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.16.tgz", + "integrity": "sha512-IDw48K2/2kRkg9LdJxurvq3lV3aBgq0REY89duEqFRthjlPdXHKMj7EnQOXVckxzgisinf3nHfrcE2FufFLXMw==", "dev": true, "license": "MIT", "dependencies": { @@ -984,9 +984,9 @@ } }, "node_modules/flatted": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.0.tgz", - "integrity": "sha512-kC6Bb+ooptOIvWj5B63EQWkF0FEnNjV2ZNkLMLZRDDduIiWeFF4iKnslwhiWxjAdbg4NzTNo6h0qLuvFrcx+Sw==", + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz", + "integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==", "dev": true, "license": "ISC" }, @@ -1033,9 +1033,9 @@ } }, "node_modules/glob/node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "version": "1.1.16", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.16.tgz", + "integrity": "sha512-IDw48K2/2kRkg9LdJxurvq3lV3aBgq0REY89duEqFRthjlPdXHKMj7EnQOXVckxzgisinf3nHfrcE2FufFLXMw==", "dev": true, "license": "MIT", "dependencies": { @@ -1217,10 +1217,20 @@ "license": "ISC" }, "node_modules/js-yaml": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", - "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.0.tgz", + "integrity": "sha512-1td788aAnnZ5qs7V2QIRl1owjtYpbKt749Y3xauqQgwIIGF/xXWz1wMTEBx5O3LK3lXLVuqXPdPxj2BoFHaW9Q==", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/puzrin" + }, + { + "type": "github", + "url": "https://github.com/sponsors/nodeca" + } + ], "license": "MIT", "dependencies": { "argparse": "^2.0.1" @@ -1465,9 +1475,9 @@ } }, "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", "dev": true, "license": "MIT", "engines": { From f88235dbd51ead702de1c6701229b32b22cdaaf1 Mon Sep 17 00:00:00 2001 From: M9nx Date: Wed, 22 Jul 2026 09:11:06 +0300 Subject: [PATCH 2/3] docs(audit): add reconciled codebase audit and release plan - Environment and functional inventory - Python, Rust, VS Code, architecture, security, and performance reports - Findings register - Four-release roadmap - Implementation sequence - Traceability audit - Evidence limitations - F-21 false-positive removal --- docs/audit/01-environment-baseline.md | 143 ++ docs/audit/02-functional-inventory.md | 100 + docs/audit/03-python-audit.md | 239 ++ docs/audit/04-rust-audit.md | 152 ++ docs/audit/05-vscode-extension-audit.md | 119 + docs/audit/06-security-audit.md | 152 ++ docs/audit/07-architecture-audit.md | 139 ++ docs/audit/08-performance-baseline.md | 101 + docs/audit/09-findings-register.md | 119 + docs/audit/10-release-roadmap.md | 128 ++ docs/audit/11-implementation-sequence.md | 130 ++ docs/audit/12-traceability-audit.md | 77 + docs/audit/audit_report.md | 182 ++ docs/audit/evidence/EVIDENCE_INDEX.md | 39 + docs/audit/evidence/environment/versions.txt | 10 + docs/audit/evidence/git/git-log.txt | 5 + docs/audit/evidence/git/git-status.txt | 2041 +++++++++++++++++ .../evidence/node/npm-audit-after-fix.txt | 42 + .../evidence/node/npm-audit-omit-dev.txt | 5 + docs/audit/evidence/node/npm-compile.txt | 5 + docs/audit/evidence/python/mypy-baseline.txt | 32 + .../security/bandit-all-including-tests.txt | Bin 0 -> 4758692 bytes docs/audit/evidence/security/pip-audit.txt | 8 + 23 files changed, 3968 insertions(+) create mode 100644 docs/audit/01-environment-baseline.md create mode 100644 docs/audit/02-functional-inventory.md create mode 100644 docs/audit/03-python-audit.md create mode 100644 docs/audit/04-rust-audit.md create mode 100644 docs/audit/05-vscode-extension-audit.md create mode 100644 docs/audit/06-security-audit.md create mode 100644 docs/audit/07-architecture-audit.md create mode 100644 docs/audit/08-performance-baseline.md create mode 100644 docs/audit/09-findings-register.md create mode 100644 docs/audit/10-release-roadmap.md create mode 100644 docs/audit/11-implementation-sequence.md create mode 100644 docs/audit/12-traceability-audit.md create mode 100644 docs/audit/audit_report.md create mode 100644 docs/audit/evidence/EVIDENCE_INDEX.md create mode 100644 docs/audit/evidence/environment/versions.txt create mode 100644 docs/audit/evidence/git/git-log.txt create mode 100644 docs/audit/evidence/git/git-status.txt create mode 100644 docs/audit/evidence/node/npm-audit-after-fix.txt create mode 100644 docs/audit/evidence/node/npm-audit-omit-dev.txt create mode 100644 docs/audit/evidence/node/npm-compile.txt create mode 100644 docs/audit/evidence/python/mypy-baseline.txt create mode 100644 docs/audit/evidence/security/bandit-all-including-tests.txt create mode 100644 docs/audit/evidence/security/pip-audit.txt diff --git a/docs/audit/01-environment-baseline.md b/docs/audit/01-environment-baseline.md new file mode 100644 index 0000000..46ce01b --- /dev/null +++ b/docs/audit/01-environment-baseline.md @@ -0,0 +1,143 @@ +# 01 — Environment Baseline (Corrected v2) + +**Audit Date:** 2026-07-22 +**Auditor:** Senior Software Architect / Code Quality Auditor + +--- + +## Git State + +| Check | Result | +|-------|--------| +| Branch | `main` | +| Commit | `555506632fa76662318dacfa07d6f6c068393758` | +| Working-tree status | **Dirty** — configuration modified and reports added. No application source files modified. | + +### Exact Changed Repository Files + +```text + M pyproject.toml + M vscode-extension/package-lock.json +``` + +Additionally, untracked files (`??`) exist, primarily consisting of: +- `uv.lock` exists locally but is untracked and not committed or enforced by CI. +- `docs/audit/` and `docs/audit/evidence/` (generated reports and documentation) +- Various build artifacts and log files (`mypy_report.txt`, `pytest_report.txt`, `radon_report.txt`, `codexa-core/target/`) + +**Nature of changes:** +- `pyproject.toml`: Configuration change (added `mypy` to dev dependencies). +- `vscode-extension/package-lock.json`: Configuration/lockfile change (from running `npm audit fix`). +- `uv.lock`: Generated lockfile. +- All other additions: Generated output or reports. +- **Application code:** Untouched. + +--- + +## Environment Validation Table + +| Check | Result | Evidence | Impact | +|-------|--------|----------|--------| +| Python version | Python 3.13.9 (via `py`) | `py --version` | Supported (≥3.11 required) | +| `python` alias | **Not found** on PATH | `python --version` fails | Forces use of `py`; CI uses `python -m pip` which may fail | +| `python3` alias | **Not found** on PATH | `python3 --version` fails | Same impact as above | +| uv package manager | uv 0.10.9 | `uv --version` | Available as Python install fallback | +| Rust / Cargo | 1.94.0 (stable) | `cargo --version` | Supported | +| rustup | 1.28.2 | `rustup --version` | Present | +| rustc | 1.94.0 (4a4ef493e) | Via rustup | Supported | +| Node.js | v24.5.0 | `node.exe --version` | Supported | +| npm | 11.10.0 | `npm.cmd --version` | Supported | +| PowerShell execution policy | Restricted for `.ps1` scripts | `npm.ps1 cannot be loaded` | **Blocks** `npm` shorthand; must use `npm.cmd` | +| `mypy` | **Installed** | `uv run mypy` runs | Type checking baseline successfully captured | +| mingw gcc linker | Present but `lpython313` not found | `cargo test` link error | **Blocks** native Rust tests on Windows | +| `codexa_core` Rust wheel | Not built/installed | `use_rust()` returns False | Extension runs Python-only fallback; Rust path not tested | +| VS Code extension compiled | `tsc -p ./` succeeds | `npm run compile` exit 0 | Extension can be built | +| ESLint config | **Missing** `.eslintrc*` | `eslint` "couldn't find config" | Linting non-functional | +| `cargo audit` | Not run (cargo-audit not installed) | — | Supply-chain check skipped | +| `pip-audit` | **Run** on requirements.txt | Exit 0 | **0 known vulnerabilities** in core production deps | + +--- + +## Repository Structure + +``` +CodexA/ +├── .github/ +│ ├── workflows/ +│ │ ├── ci.yml # Python tests only; no mypy, no coverage gate +│ │ ├── build-wheels.yml # Rust wheel builds + PyPI publish on tag +│ │ └── deploy-docs.yml # VitePress docs deploy +│ ├── ISSUE_TEMPLATE/ +│ ├── PULL_REQUEST_TEMPLATE.md +│ └── copilot-instructions.md +├── codexa-core/ # Rust native extension (PyO3) +│ ├── Cargo.toml # version 0.1.0 (diverged from Python 0.5.0) +│ ├── src/ +│ │ ├── lib.rs # PyO3 module registration +│ │ ├── ann.rs # Flat vector store (replaces FAISS) +│ │ ├── hnsw.rs # HNSW ANN search +│ │ ├── bm25.rs # BM25 keyword index +│ │ ├── chunk.rs # Line-boundary code chunker +│ │ ├── ast_chunk.rs # Tree-sitter AST-aware chunker +│ │ ├── scan.rs # File scanner (blake3, parallel) +│ │ ├── hybrid.rs # Reciprocal Rank Fusion +│ │ ├── embed.rs # ONNX embedder (optional feature) +│ │ └── tantivy_search.rs # Tantivy full-text (optional feature) +├── semantic_code_intelligence/ # Python core (23,104 LoC production) +│ ├── cli/ # 40 command files + main.py + router.py +│ ├── analysis/ # Code quality, metrics, impact +│ ├── bridge/ # HTTP bridge server +│ ├── config/ # Settings, AppConfig +│ ├── context/ # AI context windows, memory +│ ├── daemon/ # File watcher +│ ├── docs/ # Doc generation +│ ├── embeddings/ # Model registry, enhanced embeddings +│ ├── evolution/ # Self-improving dev loop +│ ├── indexing/ # Parallel indexer, scanner, semantic chunker +│ ├── llm/ # LLM providers, RAG, reasoning, streaming +│ ├── lsp/ # LSP server stub +│ ├── mcp/ # MCP server (13 tools), Claude config +│ ├── parsing/ # tree-sitter parser +│ ├── plugins/ # Plugin system (22 hooks) +│ ├── scalability/ # Multi-repo, chunking strategies +│ ├── search/ # grep, hybrid, keyword, semantic +│ ├── services/ # IndexingService, SearchService +│ ├── sessions/ # Multi-agent session management +│ ├── storage/ # VectorStore, HashStore, SymbolRegistry +│ ├── tools/ # AI agent tool protocol (13 tools) +│ ├── tui/ # Textual TUI / fallback REPL +│ ├── utils/ # Logging, helpers +│ ├── web/ # Web UI + REST API +│ ├── workspace/ # Multi-repo workspace +│ ├── rust_backend.py # Rust integration bridge +│ └── tests/ # 46 test files +├── vscode-extension/ +│ ├── src/extension.ts # Single 1,121-line TypeScript file +│ ├── package.json # v0.2.0 — ESLint 8 devDep, no eslintrc +│ └── tsconfig.json +├── docs/ # VitePress documentation +├── pyproject.toml # v0.5.0 — authoritative Python package config +├── requirements.txt # Duplicate of pyproject.toml deps (not pinned) +├── Dockerfile +├── codexa.spec # PyInstaller spec +└── package.json # Root: VitePress docs only +``` + +--- + +## Build Systems + +| Component | Build System | Command | +|-----------|-------------|---------| +| Python package | setuptools + pyproject.toml | `uv pip install -e .` | +| Rust extension | maturin (wheel only) / cargo (dev) | `maturin develop` or `cargo build` | +| VS Code extension | tsc (TypeScript) | `npm run compile` | +| Documentation | VitePress (Node.js) | `npm run docs:dev` | +| Standalone binary | PyInstaller | `pyinstaller codexa.spec` | + +--- + +## Environmental Limitations Affecting Audit + +1. **Rust extension cannot link on Windows MinGW**: `cargo test` and `cargo build` (debug) fail because MinGW-GCC cannot locate `lpython313`. This is a **Windows-specific build environment defect**, not a code defect. +2. **`cargo-audit` not installed**: Supply-chain audit of Rust crates was performed via `Cargo.lock` inspection only. diff --git a/docs/audit/02-functional-inventory.md b/docs/audit/02-functional-inventory.md new file mode 100644 index 0000000..cd982aa --- /dev/null +++ b/docs/audit/02-functional-inventory.md @@ -0,0 +1,100 @@ +# 02 — Functional Inventory (Corrected v2) + +**Correction date:** 2026-07-22 +**Changes from v1:** +- Replaced "verified working" with correct terminology: Source-confirmed, Unit-tested, Environment-blocked, etc. +- Explicitly distinguished Python-fallback, Rust-native, VS Code live-host, HTTP/MCP external-client, and mocked LLM-provider behaviour paths +- Removed claims about Rust-native behaviour being "tested" (wheel not installed) + +--- + +## Validation Terminology + +| Term | Meaning | +|------|---------| +| **Source-confirmed** | Code path exists and is structured correctly; not executed during this audit | +| **Unit-tested** | pytest unit tests cover the Python-fallback path | +| **Integration-tested** | Multiple components tested together (HTTP, DB, etc.) | +| **Manually smoke-tested** | Manually executed and observed to function | +| **End-to-end validated** | Full user flow from UI/CLI to storage tested | +| **Environment-blocked** | Could not be validated; environment constraint prevented execution | +| **Unverified** | No evidence of correct behaviour | + +--- + +## Feature Inventory + +| Feature | Component | Entry Point | Python-Fallback Status | Rust-Native Status | VS Code Status | HTTP/MCP Status | Test Coverage | Notes | +|---------|-----------|------------|----------------------|--------------------|--------------|----------------|--------------|-------| +| **Repository indexing** | `services/indexing_service.py` | `codexa index` | Unit-tested | Environment-blocked (wheel absent) | Source-confirmed | Unverified | 84% | — | +| **Incremental indexing** | `services/indexing_service.py` | `codexa index --add` / watch | Unit-tested | Environment-blocked | Source-confirmed | Unverified | 84% (shared) | — | +| **Force re-index** | `services/indexing_service.py` | `codexa index --force` | Unit-tested | N/A | Source-confirmed | Unverified | Tested | — | +| **Model-consistency guard** | `indexing/ + storage/` | Automatic on `index` | Unit-tested | N/A | N/A | N/A | Tested | — | +| **`.codexaignore` support** | `indexing/scanner.py` | Automatic | Unit-tested | Environment-blocked | N/A | N/A | 90% | — | +| **Ctrl+C partial-save** | `cli/commands/index_cmd.py` | Signal handler | Unit-tested | N/A | N/A | N/A | Tested | Windows SIGINT may not work in all terminals | +| **Parallel indexing** | `indexing/parallel.py` | Automatic | Unit-tested | Environment-blocked | N/A | N/A | 97% | — | +| **Semantic search (Python/FAISS)** | `services/search_service.py` | `codexa search` | Unit-tested | Environment-blocked | Source-confirmed | Unverified | 94% | Requires `codexa[ml]` | +| **Keyword / BM25 search** | `search/keyword_search.py` | `codexa search --mode keyword` | Unit-tested | Environment-blocked | Source-confirmed | Unverified | 75% | — | +| **Hybrid search (RRF)** | `search/hybrid_search.py` | `codexa search --mode hybrid` | Unit-tested | Environment-blocked | Source-confirmed | Unverified | 90% | — | +| **Regex / grep search** | `search/grep.py` | `codexa grep` | Unverified (21% coverage) | N/A | Source-confirmed | Unverified | **21%** | Low coverage; subprocess paths untested | +| **File-watch daemon** | `daemon/watcher.py` | `codexa watch` | Unit-tested (75%) | N/A | Source-confirmed | Unverified | 75% | Native watcher platform layer not tested | +| **Symbol extraction / parsing** | `parsing/parser.py` | Core (internal) | Unit-tested | Environment-blocked | N/A | N/A | 97% | — | +| **Symbol explanation** | `analysis/ + tools` | `codexa explain` | Unit-tested | N/A | Source-confirmed | Unverified | 84% | — | +| **Code context windows** | `context/` | `codexa context` | Unit-tested | N/A | Source-confirmed | Unverified | 95% | — | +| **Repository summary** | `analysis/` | `codexa summary` | Unit-tested | N/A | Source-confirmed | Unverified | Tested | — | +| **Dependency map** | `analysis/` | `codexa deps` | Unit-tested | N/A | Source-confirmed | Unverified | Tested | — | +| **Call graph** | `analysis/` | `codexa tool run get_call_graph` | Unit-tested | N/A | Source-confirmed | Unverified | Tested | — | +| **Code quality** | `analysis/` | `codexa quality` | Unit-tested | N/A | Source-confirmed | Unverified | Tested | — | +| **Code metrics** | `analysis/` | `codexa metrics` | Unit-tested | N/A | Source-confirmed | Unverified | Tested | — | +| **Hotspots** | `analysis/` | `codexa hotspots` | Unit-tested | N/A | Source-confirmed | Unverified | Tested | — | +| **Quality gate (CI)** | `analysis/` | `codexa gate` | Unit-tested | N/A | N/A | N/A | Tested | — | +| **Impact analysis** | `analysis/` | `codexa impact` | Unit-tested | N/A | Source-confirmed | Unverified | Tested | `analyze_impact` D-complexity | +| **AI Q&A (LLM)** | `llm/` | `codexa ask` | Mocked-LLM tested | N/A | Source-confirmed | Unverified | 48–59% | Real API calls unverified | +| **Code review (LLM)** | `llm/` | `codexa review` | Mocked-LLM tested | N/A | Source-confirmed | Unverified | Low | — | +| **Refactor suggestions** | `llm/` | `codexa refactor` | Mocked-LLM tested | N/A | Source-confirmed | Unverified | Low | — | +| **RAG pipeline** | `llm/rag.py` | Internal | Mocked-LLM tested | N/A | N/A | N/A | 77% | — | +| **Streaming responses** | `llm/streaming.py` | Internal | Mocked-LLM tested | N/A | N/A | N/A | **49%** | Under-tested | +| **Multi-turn chat** | `llm/conversation.py` | `codexa chat` | Unit-tested | N/A | Source-confirmed | Unverified | 95% | — | +| **Autonomous investigation** | `llm/investigation.py` | `codexa investigate` | Mocked-LLM tested | N/A | Source-confirmed | Unverified | **59%** | Experimental | +| **Cross-refactor** | `llm/cross_refactor.py` | `codexa cross-refactor` | Mocked-LLM tested | N/A | Source-confirmed | Unverified | **53%** | Experimental | +| **Self-improving evolution** | `evolution/` | `codexa evolve` | Unverified (67–83%) | N/A | N/A | N/A | 67–83% | Experimental | +| **PR summary** | `cli/commands/pr_summary_cmd.py` | `codexa pr-summary` | Source-confirmed | N/A | N/A | N/A | Low | — | +| **HTTP bridge server** | `bridge/` | `codexa serve` | Source-confirmed | N/A | N/A | Unverified | Not directly tested | — | +| **MCP server** | `mcp/__init__.py` | `codexa mcp` | Unverified (30%) | N/A | N/A | Unverified | **30%** | External-client behaviour unverified | +| **Claude Desktop auto-config** | `mcp/claude_config.py` | `codexa mcp --claude-config` | Unverified (**0%**) | N/A | N/A | N/A | **0%** | Entirely untested | +| **AI Agent Tool Protocol** | `tools/` | `codexa tool run/list/schema` | Unit-tested | N/A | Source-confirmed | Unverified | 84–99% | — | +| **Plugin system** | `plugins/` | `codexa plugin` | Unit-tested | N/A | N/A | N/A | 97% | — | +| **Workspace (multi-repo)** | `workspace/` | `codexa workspace` | Unit-tested | N/A | N/A | N/A | 91% | — | +| **TUI (Textual)** | `tui/` | `codexa tui` | Unverified (21%) | N/A | N/A | N/A | **21%** | D-complexity fallback repl | +| **Web UI** | `web/` | `codexa web` | Unverified (16–20%) | N/A | N/A | Unverified | **16–20%** | Severely under-tested | +| **Visualization (Mermaid)** | `web/visualize.py` | `codexa viz` | Unit-tested | N/A | N/A | N/A | 98% | — | +| **LSP server** | `lsp/` | `codexa lsp` | Unverified (39%) | N/A | N/A | Unverified | **39%** | Likely incomplete | +| **Configuration** | `config/settings.py` | `codexa init` | Unit-tested | N/A | N/A | N/A | Tested | — | +| **Model management** | `embeddings/model_registry.py` | `codexa models` | Unit-tested | N/A | Source-confirmed | N/A | 94% | — | +| **Doctor / health check** | `cli/commands/doctor_cmd.py` | `codexa doctor` | Unit-tested | N/A | Source-confirmed | N/A | Tested | — | +| **Logging** | `utils/logging.py` | Internal | Unit-tested | N/A | N/A | N/A | 98% | — | +| **VS Code sidebar (4 panels)** | `vscode-extension/src/extension.ts` | Extension activation | Source-confirmed | N/A | **Unverified** | N/A | **No tests** | Live host not tested | +| **VS Code keybindings** | `extension.ts` | Ctrl+Shift+F5/E/Q | Source-confirmed | N/A | **Unverified** | N/A | No tests | — | +| **VS Code CodeLens** | `extension.ts` | Editor | **Not implemented** | N/A | N/A | N/A | — | README claims it; source does not implement it | +| **Rust vector store (flat)** | `codexa-core/src/ann.rs` | When wheel installed | Environment-blocked | Environment-blocked | N/A | N/A | Not testable | Wheel not built | +| **Rust HNSW** | `codexa-core/src/hnsw.rs` | When wheel installed | Environment-blocked | Environment-blocked | N/A | N/A | Not testable | Same | +| **Rust BM25** | `codexa-core/src/bm25.rs` | When wheel installed | Environment-blocked | Environment-blocked | N/A | N/A | Not testable | Same | +| **Rust AST chunker** | `codexa-core/src/ast_chunk.rs` | When wheel installed | Environment-blocked | Environment-blocked | N/A | N/A | Not testable | Same | +| **ONNX embedding** | `codexa-core/src/embed.rs` | Optional feature | Environment-blocked | Environment-blocked | N/A | N/A | Not testable | Optional compile feature | +| **Tantivy full-text** | `codexa-core/src/tantivy_search.rs` | Optional feature | Environment-blocked | Environment-blocked | N/A | N/A | Not testable | Optional compile feature | +| **Editor plugins (Zed, JetBrains, etc.)** | `editors/` | External | **Not implemented** | N/A | N/A | N/A | — | README lists them; no code exists | + +--- + +## Features Requiring Immediate Attention + +| Feature | Issue | Finding | +|---------|-------|---------| +| VS Code CodeLens | Claimed in README; not in source | F-19 | +| Editor plugins (Zed, JetBrains, etc.) | Listed in README; not in repository | F-20 | +| MCP Claude auto-config | 0% coverage, unverified | F-09 | +| LSP server | 39% coverage, likely incomplete | F-13 | +| Web server | 16% coverage, unverified | F-10 | +| grep/search | 21% coverage, unverified | F-12 | +| LLM streaming | 49% coverage, mocked LLM only | F-14 | +| Cross-refactor | 53% coverage, mocked LLM only | — | diff --git a/docs/audit/03-python-audit.md b/docs/audit/03-python-audit.md new file mode 100644 index 0000000..921dc57 --- /dev/null +++ b/docs/audit/03-python-audit.md @@ -0,0 +1,239 @@ +# 03 — Python Core Audit (Corrected v2) + +**Correction date:** 2026-07-22 +**Changes from v1:** +- Bandit claim "no CVEs" removed — Bandit does not assess CVEs +- pip-audit result added (run this session) +- mypy baseline expanded per § 5 correction requirements +- Removed broad `--ignore-missing-imports` from R1 acceptance criteria; scoped per correction requirement +- Coverage summary corrected to distinguish Python-fallback and Rust-native behaviour paths + +--- + +## Commands Executed This Session (2026-07-22) + +| Command | Exit Code | Evidence File | +|---------|-----------|---------------| +| `uv run mypy semantic_code_intelligence --ignore-missing-imports` | 1 (99 errors) | `evidence/python/mypy-baseline.txt` | +| `pip-audit --requirement requirements.txt` | 1 (0 known vulns) | `evidence/security/pip-audit.txt` | + +## Commands Executed in Prior Session (2026-07-22, before checkpoint) + +| Command | Exit Code | Evidence | +|---------|-----------|---------| +| `uv run pytest --cov=semantic_code_intelligence` | 0 (passed) | `pytest_report.txt` (retained in repo root) | +| `uv run bandit -r ... -x tests -f txt` | 1 (issues found) | `bandit_report.txt` (retained in repo root) | +| `uv run radon cc -a -na` | 0 | `radon_report.txt` (retained in repo root) | + +## Commands Blocked + +| Command | Reason | +|---------|--------| +| `mypy` without `--ignore-missing-imports` | 145 files; stub coverage incomplete; full run was not captured before this session | +| Full `pip-audit` (installed env) | `uv.lock` not committed; full env audit not run | +| `uv run mypy --strict` | Would add errors from missing stubs; not appropriate for initial baseline | + +--- + +## 1. Test Results — Source-Confirmed + +| Metric | Value | Status | +|--------|-------|--------| +| Tests collected | 2,669 | — | +| Tests passed | **2,669** | ✅ (prior session) | +| Tests failed | 0 | ✅ | +| Warnings | 5 | Minor | +| Duration | 453.29 s (7m 33s) | Acceptable | +| Coverage (total) | **70.92%** | ✅ Meets 70% gate | +| Production code lines | 23,104 | Excludes tests | + +**Behaviour path distinction:** +- All 2,669 tests run against the Python-only path. The Rust-native path is **not tested** because `codexa_core` is not installed. Any coverage or test-pass claim for Rust-accelerated code paths is **unverified** in this environment. +- LLM provider tests use mocks. Real API calls are **not tested**. +- VS Code live-host behaviour is **not tested** — no extension test suite exists. +- HTTP/MCP external-client behaviour has very low unit test coverage (web/server 16%, mcp 30%). + +--- + +## 2. Coverage Analysis — Source-Confirmed + +### Overall: 70.92% (global gate met) + +**Coverage policy (selected):** +- Global line coverage: ≥ 70% during stabilization +- Critical-module line coverage: ≥ 85% (target for R2) +- Mandatory behavioural scenarios required regardless of percentage (see § 10 below) + +### Modules with Critically Low Coverage + +| Module | Coverage | Behaviour Path | Risk | +|--------|----------|---------------|------| +| `web/server.py` | **16%** | Python-fallback | HTTP bridge; error handling and routing untested | +| `web/api.py` | **20%** | Python-fallback | REST API; all handlers essentially untested | +| `search/grep.py` | **21%** | Python-fallback | Subprocess calls; security-relevant path | +| `tui/__init__.py` | **21%** | Python-fallback | D-complexity function; TUI fallback | +| `mcp/__init__.py` | **30%** | Python-fallback | MCP server; 13 tools exposed to external agents | +| `lsp/__init__.py` | **39%** | Python-fallback | LSP server; likely incomplete | +| `llm/streaming.py` | **49%** | Python-fallback (mock LLM) | Token streaming failure → silent data loss | +| `web/ui.py` | **47%** | Python-fallback | Web UI page handlers | +| `llm/openai_provider.py` | **48%** | Mocked LLM | All OpenAI calls; error handling untested | +| `llm/investigation.py` | **59%** | Mocked LLM | Autonomous agent | +| `rust_backend.py` | **44%** | Python-only (Rust wheel absent) | 56% of branches structurally unreachable | +| `mcp/claude_config.py` | **0%** | Python-fallback | Completely untested | + +### Mandatory Behavioural Scenarios (Coverage Agnostic) + +The following scenarios must be explicitly implemented in the test suite regardless of percentage achieved: + +| Scenario | Module | Current Status | +|----------|--------|---------------| +| HTTP malformed input → correct 4xx response | `web/server.py`, `web/api.py` | **Missing** | +| Path traversal in file arguments → rejection | `search/grep.py`, `web/` | **Missing** | +| MCP tool failure → structured error response | `mcp/__init__.py` | **Missing** | +| Claude config backup and rollback on failure | `mcp/claude_config.py` | **Missing** | +| Grep timeout and pattern-length rejection | `search/grep.py` | **Missing** | +| LLM streaming interruption → partial result | `llm/streaming.py` | **Missing** | +| Rust backend absent → Python fallback, logged at INFO | `rust_backend.py` | **Missing** | +| Storage schema version mismatch → clear error | `storage/` | **Missing** | + +--- + +## 3. Complexity Analysis — Source-Confirmed + +| Metric | Value | Status | +|--------|-------|--------| +| Average CC | A (3.10) | ✅ Excellent | +| D-ranked functions | `analyze_impact`, `build_change_summary`, `_run_fallback_repl` | Warning | + +--- + +## 4. Security Audit — Bandit (Production Code Only) + +**Scope:** 23,104 lines of production code (tests excluded via `-x tests`). + +**Important:** Bandit assesses **code patterns**, not dependency CVEs. Claims about dependency vulnerability status must come from `pip-audit` or `safety`, not from Bandit. + +| Severity | Count (Production) | +|----------|-------------------| +| High | **0** ✅ | +| Medium | **3** | +| Low | **26** | + +Medium findings (production only): Two B310 `urlopen` scheme issues in `llm/` and `web/`. One B603 subprocess in `search/grep.py`. See `06-security-audit.md` for full analysis. + +--- + +## 5. Python Dependency Audit — pip-audit + +**Command run this session:** `pip-audit --requirement requirements.txt` +**Result:** No vulnerabilities were reported in the attempted `requirements.txt` audit, but the evidence metadata must be reconciled. +**Scope:** `requirements.txt` (core + test deps only) +**Limitation:** ml/dev/tui extras not audited; no `uv.lock` committed; full environment audit incomplete +**Evidence:** `docs/audit/evidence/security/pip-audit.txt` + +--- + +## 6. Type Checking (mypy) Baseline — NEW this session + +**Command run this session:** `uv run mypy semantic_code_intelligence --ignore-missing-imports` +**Result:** **99 errors in 30 files** (checked 145 source files) +**mypy version:** 2.3.0 (installed this session) +**Evidence:** `docs/audit/evidence/python/mypy-baseline.txt` + +### Error Breakdown by Package + +| Package | Error Count | Notes | +|---------|------------|-------| +| `cli/` | 44 | Largest single source; command files | +| `rust_backend.py` | 13 | Optional import type stubs missing | +| `mcp/` | 10 | Type inconsistencies | +| `storage/` | 10 | Type inconsistencies | +| `ci/` | 8 | — | +| `web/` | 5 | Incompatible assignment types (confirmed) | +| `llm/` | 3 | — | +| `lsp/` | 2 | — | +| Other | 4 | `tui`, `search`, `workspace`, `analysis` | +| **Total** | **99** | — | + +### Confirmed Error Examples (from `web/server.py`) + +``` +web/server.py:162: error: Incompatible types in assignment + (expression: HotspotReport, variable: QualityReport) [assignment] +web/server.py:221: error: Incompatible types in assignment + (expression: OllamaProvider, variable: OpenAIProvider) [assignment] +web/server.py:287: error: Incompatible types in assignment + (expression: ToolExecutionResult, variable: AskResult) [assignment] +``` + +These are **real type errors** correlating with `web/server.py` having only 16% coverage — the type errors in this module are not tested. + +### mypy Remediation Plan (§ 5 correction requirement) + +**R1 scope — Install and establish baseline:** +1. Add `mypy>=1.0` to `pyproject.toml [dev]` ✅ (done this session via `uv add --dev mypy`) +2. Add `mypy.ini` or `[tool.mypy]` section to `pyproject.toml` with baseline config +3. Record the baseline: 99 errors in 30 files (this document serves as the record) + +**R1 scope — Enforce clean packages (no new errors):** +Select packages with ≤ 5 errors for immediate enforcement. These can reach 0 errors without a large effort: + +| Package | Errors | Action | +|---------|--------|--------| +| `tui/` | 1 | Fix and enforce | +| `search/` | 1 | Fix and enforce | +| `workspace/` | 1 | Fix and enforce | +| `analysis/` | 1 | Fix and enforce | +| `web/` | 5 | Fix and enforce | +| `lsp/` | 2 | Fix and enforce | + +**R1 gate:** Selected packages above reach 0 mypy errors. CI runs mypy on selected packages and fails on new errors. + +**R2 scope — Burn-down plan:** + +| Package | Errors | Target Release | +|---------|--------|---------------| +| `llm/` | 3 | R2 | +| `mcp/` | 10 | R2 | +| `storage/` | 10 | R2 | +| `ci/` | 8 | R2 | +| `rust_backend.py` | 13 | R2 (may require stub generation) | +| `cli/` | 44 | R2–R3 (largest; may need incremental) | + +**Repository-wide zero-error mypy is NOT a R1 requirement.** The baseline has 99 errors across 30 files; requiring zero errors in R1 is not proportionate. + +**Prohibited shortcuts:** Do not use `# type: ignore` globally, `exclude_dirs` covering tested packages, or `ignore_missing_imports = True` in `mypy.ini` without per-module scoping. + +--- + +## 7. CI Workflow Issues — Source-Confirmed + +The `ci.yml` workflow: +- Runs `pytest --tb=short -q` — **no coverage gate** +- Runs a `lint` job that only checks `python -m py_compile __init__.py` — **not real linting** +- Does **not** run `mypy`, `bandit`, or `radon` +- Uses `pip install -r requirements.txt` — **diverges from `pyproject.toml` extras** +- Does **not** test the Rust extension build +- Does **not** enforce or measure coverage + +The `build-wheels.yml` correctly tests Rust builds across platforms on tag push but is not part of the regular CI gate. + +--- + +## 8. Key Python Dependencies + +| Package | Version Specified | Notes | +|---------|------------------|----| +| click | ≥8.1.0 | Stable | +| pydantic | ≥2.0.0 | Stable | +| sentence-transformers | ≥2.2.0 (ml extra) | Used for embedding generation | +| faiss-cpu | ≥1.7.4 (ml extra) | Used for vector search (Python path) | +| mcp | ≥1.0.0 | MCP server implementation | +| tree-sitter | ≥0.21.0 | **API may have changed** between 0.21 and 0.26 | +| mypy | **Added this session** (2.3.0) | Must be committed to `pyproject.toml` dev deps | + +### Dependency File Duplication + +`requirements.txt` manually mirrors `pyproject.toml` dependencies without version pinning. This creates a drift risk between CI (which installs from `requirements.txt`) and the package (defined in `pyproject.toml`). + +**Recommendation:** Prefer removing `requirements.txt` as an independent source of truth and installing directly from `pyproject.toml`. Otherwise use valid requirements syntax. diff --git a/docs/audit/04-rust-audit.md b/docs/audit/04-rust-audit.md new file mode 100644 index 0000000..e0ebd1a --- /dev/null +++ b/docs/audit/04-rust-audit.md @@ -0,0 +1,152 @@ +# 04 — Rust Native Extension Audit (Corrected v2) + +**Correction date:** 2026-07-22 +**Changes from v1:** +- Removed statement "expected to pass based on code inspection" — result is environment-blocked, not inferred +- Added required CI matrix +- Separated optional-feature test failures +- Removed `cargo audit` clean claim — blocked, not assessed + +--- + +## Commands Executed + +| Command | Exit Code | Status | Evidence | +|---------|-----------|--------|---------| +| `cargo clean --manifest-path codexa-core/Cargo.toml` | 0 | Completed — removed 2,473 files, 760.2 MiB | Prior session | +| `cargo fmt --check --manifest-path codexa-core/Cargo.toml` | 1 | Formatting differences found | `evidence/rust/cargo-fmt-check.txt` (prior session report) | +| `cargo test --manifest-path codexa-core/Cargo.toml` | 1 | **Environment-blocked** — linker error | `evidence/rust/cargo-test.txt` | +| `cargo clippy --manifest-path codexa-core/Cargo.toml` | 0 (warnings) | Style warnings; not errors | Prior session | +| `cargo audit` | **Not run** | `cargo-audit` not installed | Blocked | + +--- + +## 1. Formatting (`cargo fmt --check`) + +**Status:** ❌ Formatting differences detected (prior session, confirmed via retained diff). + +**Files affected:** `src/ann.rs`, `src/ast_chunk.rs`, `src/tantivy_search.rs` + +**Nature:** All purely cosmetic — line-length wrapping of chained method calls and function signatures. No logic differences. + +**Fix:** `cargo fmt --manifest-path codexa-core/Cargo.toml` — automated; no logic change required. + +--- + +## 2. Linting (`cargo clippy`) + +**Status:** ⚠️ Style warnings present. No `#![deny(warnings)]` or `#![deny(clippy::all)]` in `lib.rs`. + +**Required CI configuration:** +```bash +cargo clippy --all-targets --all-features -- -D warnings +``` +This turns all clippy warnings into errors. This is not the current configuration. Adding `-D warnings` is a R1 work item (part of F-08 documentation/CI improvement). + +--- + +## 3. Tests (`cargo test`) — Environment-Blocked + +**Status:** ❌ **Build fails on this machine. Actual test result is unknown.** + +**Confirmed diagnosis:** Windows MinGW toolchain (`x86_64-pc-windows-gnu`) cannot locate `lpython313` in its library search path. Python 3.13 is installed via the `py` launcher but its import library (`python313.lib`) is not accessible to MinGW's `ld.exe`. + +**This is an environment defect on this machine, not a code defect.** The conclusion cannot be drawn from code inspection alone that tests would pass. The test outcome remains **unverified**. + +**Root cause confirmed (from linker output):** +``` +C:/msys64/mingw64/.../ld.exe: cannot find -lpython313: No such file or directory +``` + +**Fix options for this machine:** +1. Install Python 3.13 MSVC build and set `PYO3_PYTHON` to MSVC Python path +2. Switch Rust toolchain: `rustup default stable-x86_64-pc-windows-msvc` +3. Use WSL2 for Rust development +4. Rely on CI (GitHub Actions) for Rust test validation + +**The CI `build-wheels.yml` uses MSVC runners and does not have this issue.** However, `cargo test` is not currently run in CI — only `maturin build` (wheel creation) is validated. + +--- + +## 4. Required CI Matrix for Rust Tests + +The following CI matrix must be added as a R1 work item. + +**Feature Policy:** +* `tantivy-backend`: **Experimental**. Excluded from default release artifacts. +* `onnx`: **Experimental**. Excluded from default release artifacts due to supply-chain risk (downloads binaries at build time). + +```yaml +strategy: + matrix: + os: [ubuntu-latest, windows-latest] + features: ["", "--no-default-features", "--features tantivy-backend", "--features onnx"] + exclude: + - os: windows-latest + features: "--features onnx" +steps: + - uses: actions/checkout@v4 + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.13' + - name: cargo fmt check + run: cargo fmt --check --manifest-path codexa-core/Cargo.toml + + - name: cargo clippy + run: cargo clippy --manifest-path codexa-core/Cargo.toml --all-targets ${{ matrix.features }} -- -D warnings + + - name: cargo test + run: cargo test --manifest-path codexa-core/Cargo.toml ${{ matrix.features }} +``` + +**Optional-feature failures:** Since `--features tantivy-backend` and `--features onnx` are marked Experimental and are not shipped in the default wheels, their failures should be resolved before stabilizing them, but `continue-on-error` must **not** be used in CI if they are ever included in supported release artifacts. Until stabilized, they can be run in a separate allowable-failure CI job or omitted from the primary release gate. + +--- + +## 5. FFI Boundary Inspection — Source-Confirmed + +### Panic Safety + +All `#[pyfunction]` and `#[pymethods]` functions return `PyResult`. PyO3 normally catches panics at Python callback boundaries and raises `PanicException`, which derives from `BaseException`. This prevents ordinary `except Exception` handlers from silently swallowing Rust panics. Undefined behavior from invalid unsafe memory access is not recoverable through this mechanism. + +**Unsafe block in `ann.rs`:** +```rust +dot += unsafe { *data.get_unchecked(offset + j) } * unsafe { *q.get_unchecked(j) }; +``` +These unsafe blocks are bounded by array construction invariants (not re-verified at each access). A bug in index construction could cause undefined behaviour in release mode. This risk is low given the construction logic, but is noted. + +### Error Message Leakage + +Some error conversions include raw file paths (e.g., `format!("Load error: {e}")`), which could expose internal filesystem layout in exceptions returned to the Python caller. + +--- + +## 6. Version Divergence — Source-Confirmed + +| Component | Version | +|-----------|---------| +| Python package (`pyproject.toml`) | **0.5.0** | +| Rust crate (`codexa-core/Cargo.toml`) | **0.1.0** | +| VS Code Extension (`package.json`) | **0.2.0** | + +These versions are independent. No mechanism enforces compatibility. API breakage between Rust and Python would manifest at runtime, not at import time. + +--- + +## 7. Supply Chain — Partial Assessment + +### Cargo.lock: Source-confirmed — 77 crates locked +- `pyo3` pinned at 0.22.6 — no CVEs found in manual review +- `tantivy` pinned at 0.22.x — no CVEs found in manual review +- `instant-distance` pinned at 0.6.1 — no CVEs found in manual review + +### `cargo audit`: ENVIRONMENT-BLOCKED + +`cargo-audit` is not installed in this audit environment. **The Rust supply chain cannot be declared clean.** This is an open risk. + +**Required action:** `cargo install cargo-audit && cargo audit` in CI. See F-28. + +### ONNX Binary Download + +The `ort` crate uses `features = ["download-binaries"]`, which downloads pre-built ONNX Runtime binaries at build time from a remote host. The binary is not verified by checksum in the build script. See SEC-07 / F-23. diff --git a/docs/audit/05-vscode-extension-audit.md b/docs/audit/05-vscode-extension-audit.md new file mode 100644 index 0000000..c0b8f39 --- /dev/null +++ b/docs/audit/05-vscode-extension-audit.md @@ -0,0 +1,119 @@ +# 05 — VS Code Extension Audit (Corrected v2) + +**Correction date:** 2026-07-22 + +## Commands Executed + +```bash +cd vscode-extension +npm.cmd install # Completed successfully +npm.cmd run compile # tsc -p ./ — PASSED, exit 0, no errors +npm.cmd run lint # FAILED — ESLint: no configuration file found +npm.cmd audit # 6 high severity vulnerabilities (after npm audit fix) +npm.cmd audit --omit=dev # found 0 vulnerabilities +npm.cmd outdated # Multiple packages outdated +``` + +--- + +## 1. TypeScript Compilation + +**Status:** ✅ Compiles cleanly with zero errors. + +`tsc -p ./` produces `out/extension.js` successfully. The TypeScript code is syntactically and type-system valid. + +--- + +## 2. ESLint Configuration + +**Status:** ❌ Missing `.eslintrc` or ESLint flat config file. + +**Finding:** The `package.json` defines `"lint": "eslint src --ext ts"` using ESLint 8. ESLint 8 requires a legacy `.eslintrc.*` file (flat config was introduced in ESLint 9). No such file exists. + +**Correct fix:** Create `.eslintrc.js` with `@typescript-eslint` integration — not ESLint 9 flat config (which would require upgrading ESLint). + +The `@typescript-eslint` packages are version 6.x which is compatible with ESLint 8. An upgrade to v8.x `@typescript-eslint` packages requires ESLint v9. + +--- + +## 3. npm Dependency Audit + +### Production Dependencies: `npm audit --omit=dev` + +**Result: 0 vulnerabilities** ✅ + +The extension has **no production runtime dependencies** — all packages listed are `devDependencies`. + +### Dev Dependencies: `npm audit` (all) + +**Result: 6 vulnerabilities (after `npm audit fix`)** ⚠️ + +All 6 remaining vulnerabilities are in the `minimatch` dependency chain (used by `@typescript-eslint`). +**All 6 vulnerabilities are in dev-only dependencies** (ESLint toolchain). They are **not reachable in the packaged extension** and do not affect end users. + +**Recommended fix:** A coordinated major version upgrade of `@typescript-eslint` to v8 and `eslint` to v9 in Release 2. + +--- + +## 4. Extension Architecture Analysis + +### Structure +The entire extension (`1,121 lines`) is a single TypeScript file: `src/extension.ts`. This contains: +- Binary resolution logic (`codexBin()`) +- CLI runner wrapper (`runCodex()`) +- 4 webview providers (Search, Symbols, Quality, Tools) +- 8 command handlers +- All inline HTML/CSS/JS for webviews (~800 lines of embedded strings) + +### Commands Registered vs. Documented + +| Command ID | Title | Backend Operation | Status | +|-----------|-------|------------------|--------| +| `codexa.search` | Search Codebase | `codexa search --json` | Functional | +| `codexa.askCodexA` | Ask a Question | `codexa ask --json` | Functional | +| `codexa.callGraph` | Show Call Graph | `codexa tool run get_call_graph` | Functional | +| `codexa.models` | List Models | `codexa models list --json` | Functional | +| `codexa.quality` | Code Quality Analysis | `codexa quality --json` | Functional | +| `codexa.explainSymbol` | Explain Symbol at Cursor | `codexa tool run explain_symbol` | **Partial** — reads word at cursor but has no fallback if no word | +| `codexa.doctor` | Doctor (Health Check) | `codexa doctor --json` | Functional | +| `codexa.index` | Re-Index Codebase | `codexa index` | Functional | +| **README claims CodeLens** | — | — | ❌ **Not implemented in source** | + +--- + +## 5. Security and Reliability Findings + +#### 1. Workspace Trust Not Checked — P1 + +`codexBin()` checks for a `.venv/Scripts/codexa.exe` relative to workspace root, then falls back to `"codexa"` on PATH. +The extension **executes this binary only when the user invokes a CodexA command** (it does not execute automatically on workspace open). +However, the extension does not check `vscode.workspace.isTrusted` before executing the binary. If a malicious repository contains a `.venv/Scripts/codexa.exe`, a user invoking a command will execute the attacker's binary. + +#### 2. No Content Security Policy (CSP) in Webviews — P1 + +All four webview providers set only `enableScripts: true`. No CSP `` tag is set in any webview HTML. The current webviews render untrusted content using `escapeHtml()`, but the absence of a CSP means any XSS bypass would have no secondary defense. + +#### 3. Message Validation — P2 + +Incoming `postMessage` events from webviews are validated by `msg.type` checks, but the `msg` payload is not schema-validated. A bug in the webview JS could post malformed data to the extension host. + +#### 4. No Cancellation Support — P2 + +All async operations (`runCodex`) have no cancellation token. If a user triggers multiple searches or quality analyses rapidly, they queue up with no way to cancel. Long-running commands block the extension host. + +#### 5. Argument Injection Risk (FALSE POSITIVE) — Removed + +_Historical note:_ It was previously thought that CLI arguments constructed via `["tool", "run", "explain_symbol", "--arg", \`symbol_name=${msg.symbol}\`]` were vulnerable to flag injection. This is a **false positive**. The use of the `execFile` array combined with `a.split("=", 1)` in Python `tool_cmd.py` ensures the value is placed strictly into the arguments dictionary without secondary flag parsing. No remediation is required. + +--- + +## 6. Extension Activation and Cleanup + +- Activation events are properly scoped: `onCommand:codexa.search`, `onView:*` +- **Missing:** Neither `statusBarItem` nor `outputChannel` are added to `context.subscriptions`. They will not be properly disposed when the extension is deactivated (Memory leak on deactivation). + +--- + +## 7. Multi-root Workspace and Remote Compatibility + +The extension uses `vscode.workspace.workspaceFolders?.[0]?.uri.fsPath` — this only uses the first workspace folder. In multi-root workspaces, this is a silent limitation. Remote workspace compatibility (SSH, WSL, Containers) is not addressed. diff --git a/docs/audit/06-security-audit.md b/docs/audit/06-security-audit.md new file mode 100644 index 0000000..4fcea9d --- /dev/null +++ b/docs/audit/06-security-audit.md @@ -0,0 +1,152 @@ +# 06 — Security Audit (Corrected v2) + +**Correction date:** 2026-07-22 +**Changes from v1:** +- F-01 severity corrected to Medium (requires user interaction — user must invoke a CodexA command) +- F-02 severity corrected to Low (requires escapeHtml bypass, which has not been demonstrated) +- F-21 (CLI arg injection) removed — confirmed false positive +- Added SEC-10 as a dedicated finding for npm dev-dependency advisories +- Removed unsupported Bandit claim about "no CVEs in Python dependencies" +- Added `pip-audit` result (no known vulns in `requirements.txt`) +- Added explicit `cargo audit` blocked status +- Separated security severity, release priority, exploit preconditions, and interaction requirements + +--- + +## Security Findings Register + +| ID | Security Severity | Release Priority | Component | Exploit Preconditions | User Interaction Required | Reachability | Classification | Recommended Fix | +|----|------------------|-----------------|-----------|----------------------|--------------------------|--------------|----------------|-----------------| +| SEC-01 (= F-02) | **Low** | P1 | VS Code Extension | `escapeHtml()` must be bypassed; result must be rendered in a webview | User must receive crafted data in search/tool result | Reachable if escaping is bypassed | Defense-in-depth gap | Add nonce-based CSP `` to all webview HTML | +| SEC-02 (= F-01) | **Medium** | P1 | VS Code Extension | Attacker controls workspace; `.venv/Scripts/codexa.exe` exists in workspace root | User must **invoke** a CodexA command | Reachable: any workspace containing the crafted binary | Confirmed weakness | Check `vscode.workspace.isTrusted` before `execFile` | +| SEC-03 | **Removed** | — | — | **FALSE POSITIVE** — `execFile` argv; `split("=", 1)`; no secondary CLI parsing | — | — | — | — | +| SEC-04 (= F-36) | **Low** | P2 | Python | User supplies crafted regex pattern; Python `re` fallback must be active | User must supply pattern via `codexa grep` | Reachable if ripgrep is absent | Confirmed weakness | Add pattern-length limit (e.g., ≤ 500 chars) | +| SEC-05 (= F-30) | **Low** | P2 | Python | URL source must be attacker-controlled (config file or path traversal) | N/A (server-side) | Reachable only if config is attacker-controlled | Defense-in-depth gap | Validate scheme with `urlparse`: `if urlparse(url).scheme not in ("http", "https"): raise ValueError("Invalid URL scheme")` | +| SEC-06 (= F-18) | **Low** | P1 | Python | Python must be run with `-O` flag | N/A | Reachable only with `-O` flag; not typical for CLI use | Code standards violation | Replace `assert` with `if query_embedding is None: raise ValueError(...)` | +| SEC-07 (= F-23) | **Low** | P2 | Rust | ONNX `--features onnx` must be enabled at build time | N/A (build-time) | Build-time only; ONNX is an optional feature | Confirmed weakness | Pin ONNX binary version; verify checksum; or disable `download-binaries` | +| SEC-08 (= F-24) | **Info** | P2 | GitHub Actions | Upstream action's tag must be hijacked | N/A (CI pipeline) | Build/deploy time only | Defense-in-depth gap | Pin all `uses:` to commit SHA | +| SEC-09 (= F-27) | **Info** | P2 | Python deps | N/A | N/A | CI only | Defense-in-depth gap | Commit `uv.lock`; use `uv sync --frozen` in CI | +| SEC-10 | **Info** | P1 | Node.js / VS Code Extension | Dev-only; not in built extension | N/A | **Not reachable** in packaged extension | Dependency-scope exposure (dev toolchain only) | See detailed table below | +| SEC-11 (= F-28) | **Unknown** | P2 | Rust | N/A | N/A | Unknown — `cargo audit` not run | Requires validation | Install `cargo-audit`; run `cargo audit` in CI | +| SEC-12 (= F-37) | **Low** | P2 | Python | Config file must be committed to version control | N/A | Only if repo is shared | Operational risk | Document env-var override; add warning if key found in config on `init` | + +--- + +## Detailed Analysis + +### SEC-01 — Missing Content Security Policy in Webviews + +**Security severity: Low** +**Status:** Confirmed defense-in-depth gap. No exploit demonstrated. + +All four webview HTML strings lack a CSP `` tag. The existing `escapeHtml()` in `SHARED_JS` provides the primary XSS defense and is correctly applied before all `innerHTML` assignments. + +**Why Low (not Medium/High):** No bypass of `escapeHtml()` has been found. The CSP gap means there is no secondary defense, but the primary defense is present. + +**Remediation:** Add per-webview nonce; inject as TypeScript constant; reference in CSP `` and `