Commit Graph
258 Commits
Author SHA1 Message Date
Martin Vogel e4763a12b6 Merge branch 'main' into fix/add-gnu-source-for-strcasestr 2026-03-23 14:30:26 +01:00
Martin Vogel de322d98a3 Merge branch 'main' into fix/mcp-stdio-buffering 2026-03-23 14:20:15 +01:00
Bing Ho 3658588051 fix(platform): fall back to USERPROFILE when HOME is unset
Add cbm_get_home_dir() in platform.c: tries HOME first, then
USERPROFILE (Windows). Replace all 17 raw getenv("HOME") callsites.
Fallback from "/tmp" to cbm_tmpdir() for cross-platform temp dir.

Cherry-picked from PR #88 by @bingh0. Fixes #77.
2026-03-23 14:08:09 +01:00
Martin Vogel 296a97a337 Merge branch 'main' into fix/libgit2-diff-options-init 2026-03-23 13:30:46 +01:00
Martin Vogel fad0ff7f90 Merge PR #87: feat(k8s) — Kubernetes and Kustomize indexing (66 languages)
Adds first-class indexing for K8s manifests and Kustomize overlays:
- Resource nodes for K8s kinds (Deployment/my-app, Service/my-svc)
- Module nodes for Kustomize overlays with IMPORTS edges
- Detection via name (kustomization.yaml) and content (apiVersion:)
- Reuses vendored YAML grammar — no new tree-sitter grammar needed

Fix lint: clang-format, implicit bool conversion, magic number.
Resolve CONTRIBUTING.md conflict. Update language count 64 → 66.
Add infrastructure indexing to README features.

Closes #86. Thanks @halindrome!
2026-03-23 13:06:37 +01:00
Martin Vogel 7f33e8b49b Fix lint issues in userconfig + add custom extensions docs to README
- clang-format: fix alignment in userconfig.c and userconfig.h
- Magic number 1280 → PATH_BUF_SZ named constant
- Remove dead g-- before break in dedup loop (cppcheck)
- Add "Custom File Extensions" section to README documenting
  .codebase-memory.json and global config
2026-03-23 11:52:39 +01:00
Martin Vogel 556ccefd25 Merge branch 'main' into feat/c-user-extension-config 2026-03-23 11:41:27 +01:00
Martin Vogel eb8fcbf1ca Add commit format convention and one-issue-per-PR rule to CONTRIBUTING.md
- Commit format table: feat, fix, test, refactor, perf, docs, chore
  (adapted from @halindrome's PR #85)
- One issue per PR: no bundling multiple fixes/features
- Open an issue first: every PR must reference a tracking issue

Based on feedback from @halindrome (#84, #85) who identified the need
for structured PR guidelines and commit conventions.
2026-03-23 11:28:00 +01:00
Martin Vogel cd3b9fdd93 search_code v2: graph-augmented code search with modes + path_filter
Rewrites search_code from a raw grep wrapper into a 4-phase pipeline:
grep scan → graph block expansion → batch degree ranking → context assembly.

- Scoped grep: queries indexed file paths from graph, passes to xargs
  grep — eliminates scanning vendored/generated code (Fixes #102)
- Graph dedup: grep matches grouped into containing functions with
  in_degree, out_degree, qualified_name, label
- Three output modes: compact (default, metadata only — token efficient),
  full (with function source), files (just file paths)
- path_filter: regex on file paths (e.g. "^src/") to scope results
- context: N lines around each match (like grep -C) in compact mode
- directories: summary showing match distribution by top-level directory
- Ranking: project source first, vendored demoted, tests penalized
- Batch degree query via cbm_store_batch_count_degrees (2 SQL queries
  instead of 52 individual ones)
- Fix yyjson pointer bugs: use strcpy variants for heap/stack strings
- Add cbm_store_list_files() for indexed file enumeration
- Code discovery gate hook: per-session block (PPID-keyed) nudging
  Claude toward codebase-memory-mcp tools before grep fallback
2026-03-23 10:57:18 +01:00
Moritz Raguschat 43aca64a34 fix: add -D_GNU_SOURCE to CFLAGS for strcasestr visibility on Linux 2026-03-22 15:55:27 +07:00
Martin Vogel c38853f999 Remove Go-era cruft, update THIRD_PARTY.md for pure C project
- Delete cmd/codebase-memory-mcp/assets/ — skills and codex instructions
  are embedded as C string literals in src/cli/cli.c since v0.5.0
- Move BENCHMARK.md to docs/ to reduce root clutter
- Fix setup scripts: replace stale go build with scripts/build.sh
- THIRD_PARTY.md: replace Go module dependencies with vendored C
  libraries (sqlite3, mimalloc, mongoose, yyjson, xxhash, tre),
  fix CGo reference to static compilation
2026-03-22 01:09:12 +01:00
Martin Vogel e080233b09 Update server.json to v0.5.5, delete stale Go Makefile
- server.json: update version 0.3.1→0.5.5, 35→64 languages,
  SHA-256 hashes for current release binaries
- Remove Go Makefile (Go→C migration complete since v0.5.0)
2026-03-22 00:48:27 +01:00
DeusData df58fc94f4 Merge pull request #92 from DeusData/dependabot/github_actions/crazy-max/ghaction-virustotal-5.0.0
Bump crazy-max/ghaction-virustotal from 4.2.0 to 5.0.0
2026-03-22 00:32:49 +01:00
DeusData 9961b5db33 Merge pull request #93 from DeusData/dependabot/github_actions/actions/setup-node-6.3.0
Bump actions/setup-node from 4.4.0 to 6.3.0
2026-03-22 00:32:46 +01:00
DeusData f98c996634 Merge pull request #94 from DeusData/dependabot/github_actions/sigstore/cosign-installer-398d4b0eeef1380460a10c8013a76f728fb906ac
Bump sigstore/cosign-installer from f713795cb21599bc4e5c4b58cbad1da852d7eeb9 to 398d4b0eeef1380460a10c8013a76f728fb906ac
2026-03-22 00:32:40 +01:00
DeusData 2f0ce8c7cf Merge pull request #95 from DeusData/dependabot/github_actions/actions/attest-build-provenance-e8998f949152b193b063cb0ec769d69d929409be
Bump actions/attest-build-provenance from 96b4a1ef7235a096b17240c259729fdd70c83d45 to e8998f949152b193b063cb0ec769d69d929409be
2026-03-22 00:32:37 +01:00
Martin Vogel da7e77580f Fix Windows build: guard POSIX-only tests with #ifndef _WIN32
Path containment tests use realpath() and mkdir(path, mode) which are
not available on Windows. Shell-free exec tests already guarded.
v0.5.5
2026-03-21 23:19:50 +01:00
Martin Vogel 0888726073 Add security defense tests + eliminate system() command injection
TDD: 31 security tests covering shell injection prevention, SQLite
authorizer (ATTACH/DETACH blocked), SQL injection via Cypher, path
containment, and shell-free subprocess execution.

- Add cbm_exec_no_shell() in compat_fs: fork+execvp (POSIX), _spawnvp
  (Windows) — executes commands without shell interpretation
- Replace system() with cbm_exec_no_shell() for unzip extraction and
  version verification in update command — eliminates CodeQL
  command-line-injection alerts
- CodeQL: switch to build-mode manual for 100% source file coverage
- CodeQL gate: fix race condition between scan completion and alert API
  propagation (60s settle + double-check polling)
- Dismiss TOCTOU in pass_envscan.c (benign read-only directory walk)
2026-03-21 23:02:34 +01:00
Martin Vogel aa2b60be7d Fix 29 CodeQL alerts: command injection, snprintf overflow, TOCTOU races
- Command injection (CRITICAL): validate shell args before system() in
  update command's unzip and version-check calls
- TOCTOU cli.c: use open(O_CREAT, 0755) + fdopen() to set permissions
  atomically instead of fopen() + chmod() after close
- TOCTOU pass_envscan.c: open file first, then fstat() on fd to check
  size, eliminating stat-then-open race window
- Overflowing snprintf (11 locations): clamp offset after each append
  to prevent unsigned underflow on truncation in cypher.c, store.c,
  http_server.c, test_c_lsp.c
- Add CBM_SNPRINTF_APPEND macro in str_util.h for future safe appends
- CodeQL: remove pull_request trigger (only scan push to main)
- CodeQL gate: increase timeout from 30 to 45 minutes
- Add fuzz testing script (random JSON-RPC + Cypher mutations)
- 12 Scorecard governance alerts dismissed (not code vulnerabilities)
2026-03-21 22:18:31 +01:00
Shane McCarronandClaude Sonnet 4.6 1a7c6ae8d2 fix(k8s): add k8s pass to parallel pipeline path
The parallel execution path (used for repos above MIN_FILES_FOR_PARALLEL)
was missing the cbm_pipeline_pass_k8s() call. The pass existed only in
the sequential fallback path, so any repo large enough to trigger parallel
indexing produced zero k8s Resource and kustomize Module nodes.

Discovered via live testing against a 954-file gitops repo: the parallel
path was taken, k8s pass was silently skipped, and search_graph returned
0 Resource nodes despite 213 kustomize overlays and hundreds of manifests.

Add the pass after cbm_parallel_resolve() in the parallel branch, matching
the same pattern (fail-open, cancel check, timing log) as the sequential path.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-21 15:08:42 -05:00
Shane McCarronandClaude Sonnet 4.6 94882c26f9 fix(k8s): address QA round 3 findings
- Check return value of cbm_pipeline_pass_k8s() in incremental path;
  log warning on failure (fail-open, matches full pipeline behaviour)
- Add comment documenting pass ordering and the two known structural
  limitations: File→Resource DEFINES edges and cross-file kustomize
  IMPORTS edges are not emitted in incremental (gbuf only contains
  nodes for changed files; File nodes from pass_structure are absent)
- Fix clang-format violation in incremental_kustomize_module_indexed
  test (single-line if condition)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-21 14:59:12 -05:00
Martin Vogel 4322116349 CodeQL gate: wait for scan on current commit (max 30 min) 2026-03-21 20:51:35 +01:00
Martin Vogel f3e4eeafb1 Add CodeQL SAST + Scorecard + badges + LICENSE in archives 2026-03-21 20:44:31 +01:00
Shane McCarronandClaude Sonnet 4.6 a90ab5d37b fix(k8s): add k8s pass to incremental pipeline
cbm_pipeline_pass_k8s() was called in the full pipeline (pipeline.c)
but absent from pipeline_incremental.c. This meant k8s Resource nodes
and kustomize Module nodes were never created or updated during
incremental re-indexing — only after a fresh full index.

Add the pass after the semantic pass, following the same timing-log
pattern as the other incremental passes. Pass changed_files (not the
full file list) so only modified/added YAML files are re-processed.

Add two regression tests:
- incremental_k8s_manifest_indexed: full index + add manifest via
  incremental, verifies Resource node appears in the DB
- incremental_kustomize_module_indexed: same for kustomization.yaml
  Module node

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-21 14:38:41 -05:00
Martin Vogel 6bc40c42e3 Include LICENSE file in all release archives 2026-03-21 20:23:42 +01:00
Martin Vogel 785748cbdb Add OpenSSF Scorecard workflow (weekly + push to main) 2026-03-21 20:14:55 +01:00
Martin Vogel 6e0ad6bc61 Scorecard: threshold gate (>=4.0) instead of inline report 2026-03-21 20:11:02 +01:00
dependabot[bot] 7f984ced61 Bump crazy-max/ghaction-virustotal from 4.2.0 to 5.0.0
Bumps [crazy-max/ghaction-virustotal](https://github.com/crazy-max/ghaction-virustotal) from 4.2.0 to 5.0.0.
- [Release notes](https://github.com/crazy-max/ghaction-virustotal/releases)
- [Commits](https://github.com/crazy-max/ghaction-virustotal/compare/d34968c958ae283fe976efed637081b9f9dcf74f...936d8c5c00afe97d3d9a1af26d017cfdf26800a2)

---
updated-dependencies:
- dependency-name: crazy-max/ghaction-virustotal
  dependency-version: 5.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-21 17:51:30 +00:00
Martin Vogel d974b50304 VirusTotal: scan extracted binaries, not archives
Archives >3MB may not be unpacked by VirusTotal, meaning only the
container gets scanned (meaningless). Now extracts the actual
executables from tar.gz/zip before uploading to VirusTotal.
Users still download archives (preserves Unix permissions).
Also fixes analysis ID parsing (base64 format, not SHA256).
Also fixes SBOM format (SPDX 2.3 instead of CycloneDX).
2026-03-21 18:48:51 +01:00
Shane McCarronandClaude Sonnet 4.6 5b534ce465 fix(mcp): address QA round 2 findings
- Add explicit fallback path when fcntl(F_GETFL) fails: skip the FILE*
  peek and fall through directly to blocking poll so idle eviction still
  fires on timeout (Finding 1)
- Strengthen C unit test: verify id:1 (initialize) and id:2 (tools/list)
  response IDs are both present, not just a substring match on "tools"
  (Finding 2)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-21 12:47:11 -05:00
Martin Vogel 88f8908c41 Fix VirusTotal: use /analyses/ endpoint with base64 analysis ID 2026-03-21 18:44:37 +01:00
Shane McCarronandClaude Sonnet 4.6 5ca5f3291f fix(mcp): address QA round 1 findings
- Use O_NONBLOCK + clearerr() in Phase 2 fgetc probe to preserve the
  60s idle eviction timeout when both kernel fd and FILE* buffer are
  empty (fgetc on a blocking fd would otherwise block indefinitely,
  bypassing Phase 3 poll timeout and preventing cbm_mcp_server_evict_idle)
- Add #include <fcntl.h> for fcntl()/O_NONBLOCK
- Fix comment: "two-phase" → "three-phase" (implementation has 3 phases)
- Improve Python integration test: verify id:1 (initialize) and id:2
  (tools/list) response IDs are both present, not just "tools" substring

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-21 12:37:28 -05:00
Martin Vogel 1d0889e5f9 Fix SBOM: use SPDX 2.3 format (CycloneDX failed schema validation) 2026-03-21 18:15:42 +01:00
Martin Vogel b6c32a4f13 Skip SBOM attestation (schema validation fails), keep as release asset 2026-03-21 18:10:55 +01:00
Shane McCarron 16552befdd test(mcp): add rapid-init integration test for poll/getline buffering fix 2026-03-21 12:03:52 -05:00
Shane McCarron b8b2dd356b fix(mcp): resolve poll/getline FILE* buffering mismatch causing tools/list hang 2026-03-21 12:00:41 -05:00
Shane McCarron 2704fdf734 chore(branch): create fix/mcp-stdio-buffering off main 2026-03-21 11:59:40 -05:00
Martin Vogel 77b9e7def7 Fix SBOM: use python3 for valid JSON (heredoc indentation broke format) 2026-03-21 17:46:08 +01:00
Martin Vogel e2b7797d47 Fix ClamAV macOS: suppress X509 SSL errors in freshclam 2026-03-21 17:18:35 +01:00
dependabot[bot] 876ba6508c Bump actions/attest-build-provenance
Bumps [actions/attest-build-provenance](https://github.com/actions/attest-build-provenance) from 96b4a1ef7235a096b17240c259729fdd70c83d45 to e8998f949152b193b063cb0ec769d69d929409be.
- [Release notes](https://github.com/actions/attest-build-provenance/releases)
- [Changelog](https://github.com/actions/attest-build-provenance/blob/main/RELEASE.md)
- [Commits](https://github.com/actions/attest-build-provenance/compare/96b4a1ef7235a096b17240c259729fdd70c83d45...e8998f949152b193b063cb0ec769d69d929409be)

---
updated-dependencies:
- dependency-name: actions/attest-build-provenance
  dependency-version: e8998f949152b193b063cb0ec769d69d929409be
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-21 15:59:54 +00:00
dependabot[bot] b1297f0a9c Bump sigstore/cosign-installer
Bumps [sigstore/cosign-installer](https://github.com/sigstore/cosign-installer) from f713795cb21599bc4e5c4b58cbad1da852d7eeb9 to 398d4b0eeef1380460a10c8013a76f728fb906ac.
- [Release notes](https://github.com/sigstore/cosign-installer/releases)
- [Commits](https://github.com/sigstore/cosign-installer/compare/f713795cb21599bc4e5c4b58cbad1da852d7eeb9...398d4b0eeef1380460a10c8013a76f728fb906ac)

---
updated-dependencies:
- dependency-name: sigstore/cosign-installer
  dependency-version: 398d4b0eeef1380460a10c8013a76f728fb906ac
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-21 15:59:50 +00:00
dependabot[bot] aac0fec568 Bump actions/setup-node from 4.4.0 to 6.3.0
Bumps [actions/setup-node](https://github.com/actions/setup-node) from 4.4.0 to 6.3.0.
- [Release notes](https://github.com/actions/setup-node/releases)
- [Commits](https://github.com/actions/setup-node/compare/49933ea5288caeca8642d1e84afbd3f7d6820020...53b83947a5a98c8d113130e565377fae1a50d02f)

---
updated-dependencies:
- dependency-name: actions/setup-node
  dependency-version: 6.3.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-21 15:59:44 +00:00
Martin Vogel dd30132e2d Pin Actions to SHA + enforce via security audit + Dependabot
- All GitHub Actions pinned to immutable commit SHAs (prevents
  tag-poisoning attacks like tj-actions/changed-files incident)
- Security audit (Layer 1) now blocks unpinned Actions in CI
- Dependabot configured to auto-propose SHA updates weekly
- Pre-commit hooks tracked in scripts/hooks/ for contributors
- Time-bomb detection + MCP file read audit added to Layer 1
2026-03-21 16:57:17 +01:00
Martin Vogel c371e9f07d Add time-bomb + MCP file read audit, tracked pre-commit hooks
Security audit (Layer 1) new checks:
- Time-bomb scan: flags time()/sleep()/clock() near dangerous calls
- MCP file read audit: tracks fopen/fread count in mcp.c against
  expected max (detects data exfiltration through tool responses)

Pre-commit hooks now tracked in scripts/hooks/:
- Contributors activate with: git config core.hooksPath scripts/hooks
- Runs: lint → security audit → build + test
- setup.sh already configures this automatically
2026-03-21 16:43:48 +01:00
Martin Vogel e0bce845eb Fix SBOM: valid JSON format for attest-sbom action 2026-03-21 16:34:03 +01:00
Juha SyrjäläandClaude Opus 4.6 feeb0b1602 Fix build error with libgit2 -Wmissing-field-initializers
Build fails at pass_githistory.c:171 with:

  error: missing field 'interhunk_lines' initializer
         [-Werror,-Wmissing-field-initializers]
    git_diff_options diff_opts = GIT_DIFF_OPTIONS_INIT;

codebase-memory-mcp at 75b5dcb has this issue. The GIT_DIFF_OPTIONS_INIT
macro does not list all struct fields, which clang flags as an error
under -Werror.

Replace the macro with the runtime git_diff_options_init() API, which
properly initializes all fields. Available since libgit2 0.28.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 17:11:48 +02:00
Martin Vogel 6881812b48 VirusTotal gate: wait for 100% scan completion, no compromises
- Wait until at least 60 engines have actually scanned (not just
  reported type-unsupported/failure/timeout)
- 20 minute timeout per binary (was 5 minutes)
- If scan doesn't complete in time → FAIL (incomplete scan is not clean)
- Engines that can't scan (type-unsupported, failure, timeout) are
  excluded from the completion count
2026-03-21 16:10:54 +01:00
Martin Vogel b5490cf9b9 Clarify native AV scans passed in release notes 2026-03-21 15:51:00 +01:00
Martin Vogel e5b6ee5733 Fix ClamAV freshclam config: ensure signatures are downloaded
freshclam requires DatabaseMirror set in config. Without it, ClamAV
scans with empty signatures (catches nothing). Now properly configures
freshclam.conf on both Linux (apt) and macOS (Homebrew) before updating.
2026-03-21 15:45:54 +01:00
Martin Vogel f8862144bf Add native AV scans on all 3 platforms + update SECURITY.md
Every platform now has a real antivirus gate that fails the build:
- Windows: Windows Defender with ML heuristics (MpCmdRun.exe)
- Linux: ClamAV with freshclam signature update
- macOS: ClamAV with freshclam signature update

Any detection on any platform blocks the release-draft from being
created. This is on top of the VirusTotal zero-tolerance gate in
the verify job.

SECURITY.md updated with complete security architecture.
2026-03-21 15:39:45 +01:00