Commit Graph

336 Commits

Author SHA1 Message Date
Martin Vogel fa6bfd125f feat(py_lsp): stdlib registry from typeshed + generator
Phase 10 of Python LSP integration. Adds:

- scripts/gen-py-stdlib.py: walks a typeshed/stdlib checkout, parses
  each .pyi via Python's stdlib `ast` module, and emits one C source
  file populating cbm_python_stdlib_register. v1 simplifications:
    - overload stacks collapse to first signature
    - ParamSpec / TypeVarTuple / Concatenate skipped
    - version guards (if sys.version_info >= ...) flattened to union
      of branches
    - per-symbol min/max version guards not yet emitted (v1.1 follow-up)
  Module allowlist matches PYTHON_LSP_PLAN.md Phase 10 list — top
  stdlib modules by usage in indexed Python projects, skipping
  tkinter / turtle / curses / xml / email for size.

- internal/cbm/lsp/generated/python_stdlib_data.c (auto-generated,
  20,021 lines): 114 modules, 753 classes (2,385 methods), 794 free
  functions registered. Source pinned to typeshed commit
  a7912d521e16ff63caf7a8b64b9072542be36777 (recorded in header).
  Compiles cleanly under ASan + UBSan.

- lsp_all.c includes the generated file. The CBM_PYTHON_STDLIB_GENERATED
  macro disables py_lsp.c's no-op stub so the real registration runs.

4 new test_py_lsp.c cases verify resolution against the registry:
os.getcwd, collections.defaultdict constructor, pathlib.Path.exists
method via typed parameter, logging.getLogger.

Known v1 limitation captured in test comments: `import os.path` only
binds the leaf `path` in scope, so `os.path.join` style chained
attribute access on the parent module name doesn't yet resolve.
Phase 10.5 will stamp parent-module bindings.

All 2869 prior tests stay green; 4 new stdlib tests pass.
2026-05-09 00:39:21 +02:00
Martin Vogel 3305c1f9d3 fix(security): widen release audit to all files in binaries/
Previously the verify job only ran scripts/security-strings.sh on
files matching binaries/codebase-memory-mcp* — install.sh, install.ps1,
LICENSE, and any future companion files in the release archives were
NOT covered by the binary-string audit (only by VirusTotal).

Changes:
- release.yml: loop over binaries/* (every file in the audit set).
- security-strings.sh: detect file type via 'file -b'. For shell
  scripts and other text files, skip the URL audit and dangerous-cmd
  audit (those rules are tuned for compiled binaries — install.sh
  legitimately uses wget as a curl fallback, and 'case https://*)'
  globs look like unauthorized URLs to a strings dump). Always run
  credential and base64 pattern audits — those are universally
  meaningful regardless of file type.
- Verified locally: install.sh and install.ps1 now both pass.

Net effect: every release artifact is now audited, with rule sets
appropriate to its file type.
2026-05-05 00:59:58 +02:00
Martin Vogel 72c5bdba89 fix(security-strings): allowlist 'telnet' from rst grammar URI schemes
The rst tree-sitter grammar (added in the 89-grammar bump) contains a
valid_schemas[] array listing URI schemes (http, https, ftp, mailto,
telnet, ssh) in vendored/grammars/rst/tree_sitter_rst/chars.c. The
'telnet' string ends up in the binary's string table and tripped the
dangerous-command detector, blocking smoke on every platform.

Add an allowlist mechanism for known-benign matches with a comment
pointing at the source file, so future false positives can be
documented the same way.
2026-05-04 22:04:39 +02:00
Martin Vogel ec23b4f3e9 fix(smoke-test): parse CLI output as single JSON
The CLI's default print mode (cli_print_mcp_result in src/main.c)
unwraps the MCP envelope and prints the inner JSON directly. The
smoke test was double-parsing as if it received {content:[{text:...}]},
which silently fell through to empty values and failed every assertion
across all platforms (8 occurrences fixed).
2026-05-04 21:21:53 +02:00
test 2c8be91757 Merge branch 'worktree-add-new-languages'
# Conflicts:
#	internal/cbm/lang_specs.c
2026-04-16 10:47:10 +02:00
test 8babe67bea feat: add persistent artifact storage for team sharing
Add .codebase-memory/graph.db.zst — a zstd-compressed knowledge graph
artifact that can be committed to the repo. Teammates bootstrap from
the artifact instead of running a full reindex from scratch.

- Vendor zstd 1.5.7 (amalgamated build) for 8-13:1 compression
- Two-tier export: zstd -9 + index stripping for explicit index,
  zstd -3 for watcher/incremental auto-updates
- Import: decompress → integrity check → auto-recreate indexes
- Bootstrap in handle_index_repository: when no local DB exists but
  artifact is present, import first then run incremental
- Auto-create .gitattributes with merge=ours to prevent conflicts
- Fix: add missing idx_edges_url_path to create_user_indexes and
  url_path_gen generated column to init_schema
- 13 new tests (5 zstd wrapper + 8 artifact round-trip/edge cases)
2026-04-15 23:56:03 +02:00
test b2b48f8b0d Add 89 new tree-sitter grammars (66 to 155 languages)
Vendor, wire up, and compile 89 new tree-sitter grammars, expanding
language support from 66 to 155 languages. All grammars pass security
audit (no dangerous patterns in scanner.c files).

New programming languages (31):
  Solidity, Typst, GDScript, Gleam, PowerShell, Pascal, D, Nim, Scheme,
  Fennel, Fish, AWK, Zsh, Tcl, Ada, Agda, Racket, Odin, ReScript,
  PureScript, Nickel, Crystal, Teal, Hare, Pony, Luau, Janet, Sway,
  NASM, Assembly, TLA+, Pkl, Cairo, Move, Squirrel, ISPC, FunC, Smali

New config/data/IDL formats (31):
  Just, Astro, Blade, Go Template, Templ, Liquid, Jinja2, Prisma,
  Hyprlang, DotEnv, Diff, WGSL, KDL, JSON5, Jsonnet, RON, Thrift,
  Cap'n Proto, Properties, SSH Config, BibTeX, Starlark, Bicep, CSV,
  Requirements, HLSL, VHDL, SystemVerilog, DeviceTree, Linker Script,
  GN, Kconfig, BitBake, TableGen, Slang, LLVM IR, Smithy, WIT,
  Go Mod, Mermaid, RST, Beancount, Puppet, PO, Regex, JSDoc,
  gitattributes, gitignore, Apex, SOQL, SOSL

Infrastructure:
  - scripts/new-languages.json: manifest for all new languages
  - scripts/generate-lang-code.py: generates boilerplate from manifest
  - scripts/audit-grammar-security.sh: pre-vendoring security scanner
  - Fixed angle-bracket includes in 18 grammars
  - Fixed PureScript scanner const mismatch
  - Fixed VHDL scanner void* API signatures
  - Fixed RST tree_sitter_rst/ subdirectory include paths
  - Copied crystal unicode.c (extra scanner dependency)

All new languages start with minimal lang specs (module_types only).
Function/class/call extraction specs to be refined incrementally.
2026-04-15 21:28:51 +02:00
test 46319a53ff Add grammar security audit and enhance vendor script
- vendor-grammar.sh: copy extra headers (.h, .inc) and common/ subdirs
  from grammar src/ directories. Needed for Astro (tag.h), PureScript/
  Typst (unicode.h), VHDL (.h/.inc files), F# (common/scanner.h).

- audit-grammar-security.sh: pre-vendoring scanner for dangerous patterns
  in vendored grammar C files. Checks for dangerous includes (sys/*,
  unistd.h, dlfcn.h), dangerous calls (system, exec, popen, fopen,
  socket, getenv, fork, dlopen), and suspicious patterns (constructor
  attributes, inline assembly, base64 blobs). PASS/WARN/BLOCK per grammar.
2026-04-15 20:08:35 +02:00
Martin Vogel d3aa98e7cd Fix VirusTotal gate: accept completed scans with < 60 engines
VT's status=completed is final — no more engines will report. The script
was polling indefinitely when ARM binaries only reached 50/76 engines.
Now accepts any completed scan, logs a NOTE when below MIN_ENGINES.
2026-04-06 21:24:56 +02:00
Martin Vogel 6f268d0f91 Respect nested .gitignore files during indexing, security audit all variants
Nested .gitignore support (fixes #178):
- Load per-subdirectory .gitignore during walk, match paths relative to
  the gitignore's directory via local_rel_path()
- Root and nested gitignores stack independently
- Owned gitignores collected and freed at walk end (avoids use-after-free
  from borrowed pointers on the iterative stack)

Security:
- Run security-strings/install/network + ClamAV + Windows Defender on
  ALL binary variants (standard + UI), not just standard
- Whitelist UI bundle URLs (React, Three.js, Google Fonts, Tailwind, W3C)

Co-Authored-By: dLo999 <dLo999@users.noreply.github.com>
2026-04-06 19:44:16 +02:00
Martin Vogel 9e1e30ded0 Allow toolchain URLs in binary string audit (static build artifacts)
gcc/glibc embed bug tracker URLs (bugs.launchpad.net, gcc.gnu.org,
sourceware.org) into statically-linked binaries. These are compiler
artifacts, not our code.
2026-04-06 17:47:04 +02:00
Martin Vogel 8967d7cd41 Remove AV-triggering words from token vocabulary, revert audit allowlist
Strip 11 tokens (wget, curl, netcat, ncat, telnet, passwd, shadow,
exploit, hack, inject, malware) from Nomic vocabulary. These fall back
to sparse random vectors — negligible quality impact. Removes all
security audit exceptions: zero allowlists, zero suppressions.
2026-04-06 16:12:02 +02:00
Martin Vogel 3f7f7eeab7 Fix binary string audit: exclude bare token vocabulary matches
The embedded Nomic code token vocabulary (40K tokens) includes words like
"wget" as code tokens. Filter out bare single-word matches (2-10 lowercase
chars) since real dangerous strings appear in command context, not as
standalone vocabulary entries.
2026-04-06 15:40:11 +02:00
Martin Vogel 74099d8600 Fix smoke test: platform-specific config paths + consolidated skill name
- Set APPDATA/LOCALAPPDATA env vars for Windows so cbm_app_config_dir()
  and cbm_app_local_dir() resolve to FAKE_HOME paths
- Add Windows (*.exe) branches for Zed, KiloCode, VSCode config checks
- Add macOS branch for KiloCode (was hardcoded to .config/ on all platforms)
- Create platform-correct detection dirs (AppData on Windows, Library on
  macOS, .config on Linux) so agent detection + install paths match
- Update skill check from old 4-skill names to consolidated codebase-memory
  (old dirs are cleaned up during install since skill consolidation)
2026-04-06 15:25:09 +02:00
Martin Vogel 6e1b3b2eaf Fix smoke test: set XDG_CONFIG_HOME for portable Linux agent detection
On Alpine musl (portable builds), cbm_app_config_dir() needs explicit
XDG_CONFIG_HOME to resolve to FAKE_HOME/.config. Without it, the install
writes to the wrong path and KiloCode/Zed config checks fail.
2026-04-06 15:00:06 +02:00
Martin Vogel 894c04fc0e Fix cross-platform vector blob assembly and vendored security allowlist
- code_vectors_blob.S: preprocessor conditionals for macOS (Mach-O
  __DATA,__const + underscore prefix) vs Linux (ELF .rodata, no prefix)
- Makefile: use $(CC) -c instead of $(AS) to enable preprocessor on .S
- Add vendored/nomic to KNOWN_VENDORED security allowlist (pure int8
  vector data, zero executable code)
- Update vendored checksums
2026-04-06 12:54:13 +02:00
Martin Vogel 8a06d78ac7 Parallelize post-passes, fix mode filtering + semantic edge quality
- Parallelize pass_similarity and pass_semantic_edges via worker pool with
  thread-local edge buffers; sequential final merge since gbuf is not
  thread-safe. Adds cbm_lsh_query_into() as a thread-safe variant with
  caller-provided candidate buffer.

- Add activatable profiling subsystem (CBM_PROFILE=1 env or --profile flag)
  for step-level timing of extract, resolve, corpus build, vector phases,
  and sqlite dump. Zero overhead when disabled.

- Fix cbm_index_mode_t enum mismatch between pipeline.h (FULL=0, MODERATE=1,
  FAST=2) and discover.h (FULL=0, FAST=1). mode=fast silently no-op'd
  fast-discovery filtering because discover.c compared against the wrong
  value. Linux kernel fast mode went 1:40 -> 3:11 as a result; now back to
  1:40. Broaden the filter guard to mode != CBM_MODE_FULL so MODERATE and
  FAST both get aggressive discovery.

- Clamp cbm_sem_combined_score output to [0, 1]. The proximity multiplier
  returns up to 1.10 as a same-file boost which could push the final
  cosine score above 1.0.

- Short-circuit semantic scoring when MinHash jaccard >= 0.95. Exact
  near-clones are already emitted as SIMILAR_TO edges; returning 0 here
  avoids flooding SEMANTICALLY_RELATED with cross-service copy-paste
  boilerplate and frees the edge budget for genuine vocabulary-bridged
  relations.

- Validate search_graph semantic_query as an array of strings and return
  a clear error for a single-string input. Update the tool description
  to spell out the requirement explicitly with an example.

- JSON-escape user-controlled strings (callee names, call arguments,
  URL paths, import local_name) in call/argument properties. Introduces
  cbm_json_escape() in foundation/str_util.

- Skip SQLite pending_byte_page (file offset 0x40000000) during raw page
  writes in sqlite_writer to avoid corrupting databases that cross the
  1 GiB boundary.

- Migrate pretrained vector blob from UniXcoder (51K tokens) to
  nomic-embed-code (40856 tokens x 768d int8). Includes the extraction
  script under scripts/extract_nomic_vectors.py.
2026-04-06 12:41:30 +02:00
Martin Vogel 54c032528d Skip update when already on latest version
Check GitHub releases/latest redirect header before downloading.
Saves bandwidth and avoids unnecessary index rebuilds.

- "Already up to date" when version matches or is ahead
- --force flag to bypass the check
- Graceful degradation when network is unavailable
- Uses same curl dependency as the download itself

Fixes #142

Co-Authored-By: dLo999 <dLo999@users.noreply.github.com>
2026-04-03 17:41:27 +02:00
Martin Vogel 87188913bc Refactor CI: split monolith workflows into reusable components
Before: 2 monolith YAMLs (904 + 1127 lines), duplicated matrices,
inconsistent action versions, duplicate build-windows job.

After: 5 reusable workflows + 3 lean callers (1091 total lines):
- _lint.yml: lint + security-static + codeql-gate
- _test.yml: tests on 5 platforms with CBM_SKIP_PERF support
- _build.yml: standard + UI + portable builds, all platforms
- _smoke.yml: smoke test every binary variant
- _soak.yml: quick + ASan soak, parameterized duration

Fixes: duplicate build-windows, missing Windows CBM_SKIP_PERF,
missing timeout-minutes, inconsistent action versions,
VirusTotal check extracted to scripts/ci/check-virustotal.sh.
2026-04-02 16:57:44 +02:00
Martin Vogel 1b84943000 Separate perf tests from CI, fix cross-platform build issues
- Add CBM_SKIP_PERF=1 env var to skip incremental/perf test suite
- CI and Docker test targets skip perf by default (run.sh perf for manual)
- Convert all perf assertions to warnings (log timing, never block)
- Fix store.h anonymous enum in struct (GCC rejects, clang accepts)
- Fix test_store_search.c mkstemp on non-template path
- Add ca-certificates to Docker test image for git HTTPS
- Add cbm_gmtime_r shim in compat.h (Windows gmtime_s wrapper)
- Fix compat.c missing constants.h include (Windows build)
- Fix platform.c _environ redeclaration on mingw
- Rename trace_call_path -> trace_path in smoke/soak/fuzz scripts
2026-04-02 14:52:14 +02:00
Martin Vogel d9bd071e77 Fix lint: magic numbers in cypher/sqlite_writer/configlink/gitignore, extract URL-in-args helpers 2026-04-02 01:08:51 +02:00
Martin Vogel 7fa3acd0c6 WIP: strict linting + RAM-first pipeline (lint fixes pending) 2026-04-01 23:22:44 +02:00
Martin Vogel 6e4ca93cf0 Split 168 functions to cognitive complexity 25, zero lint errors
Lower thresholds to industry defaults:
  cognitive-complexity: 25 (was 250)
  statements: 200 (was 400)
  lines: 400 (was 800)

All 168 functions split into smaller helpers across 44 files.
Zero NOLINTNEXTLINE suppressions remain. Zero clang-tidy errors.

Add clang-tidy to scripts/lint.sh (--ci to skip where unavailable).
Fix sqlite_writer B-tree PageRef initialization. Fix Terraform struct
parsing, Louvain null guards, const qualifiers, shadow variables.

2741 tests pass.
2026-03-31 20:04:12 +02:00
Martin Vogel 80680ea367 Cross-service communication discovery + RAM-first incremental indexing
AST-based detection of HTTP calls, async dispatch (Pub/Sub, Cloud Tasks,
Kafka, SQS, etc.), and config accesses via resolved qualified names.
Route nodes as cross-service rendezvous points with infra→handler matching.
Constant propagation for module-level string assignments. YAML infrastructure
URL extraction from Cloud Scheduler configs.

RAM-first incremental pipeline: load DB into graph buffer, purge changed
file nodes, extract directly into existing buffer (resolver sees all nodes),
dump back to disk. Zero edge gap on kubernetes/django/meilisearch/neovim.

- service_patterns.c: ~170 library patterns (90 HTTP, 50 async, 30 config)
- pass_route_nodes.c: Route node creation + infra URL matching
- extract_unified.c: string constant collection + string ref classification
- extract_calls.c: first_string_arg + keyword argument extraction
- pipeline_incremental.c: RAM-first load→purge→extract→resolve→dump
- graph_buffer.c: load_from_db, delete_by_file, foreach visitors
- C++ LSP crash fix: NULL guard in cbm_type_substitute
2026-03-28 13:59:42 +01:00
Martin Vogel 007980c0eb Fix C++ SEGV: NULL deref in LSP type resolver on large header files
Root cause: c_eval_expr_type_inner has 42 places accessing ptr->kind
on CBMType* pointers. Some code paths (cbm_type_substitute, internal
lookups) return NULL on unusual C++ AST shapes (deeply nested
templates, 300+ defs per file). NULL->kind = SIGSEGV.

Fix: safe_kind() inline returns CBM_TYPE_UNKNOWN for NULL pointers.
All 42 ->kind accesses in c_eval_expr_type_inner replaced.
Also: recursion depth guard (256), cbm_type_substitute returns
cbm_type_unknown() for NULL input, walk_usages/walk_env depth limits.

Verified: spdlog (previously crashed) now indexes 2526 nodes, 5518 edges.
All 2586 tests pass.
2026-03-26 16:19:10 +01:00
Martin Vogel f52376b982 Update: 2586 tests, 66 languages everywhere, tre vendored hash 2026-03-26 11:53:35 +01:00
Martin Vogel 0c81278777 Raise soak query latency threshold to 60s (MSYS2 overhead) 2026-03-26 11:14:57 +01:00
Martin Vogel de2b55bfe1 Fix Windows smoke 12a: normalize MSYS2 uname to 'windows' for archive name 2026-03-26 10:47:07 +01:00
Martin Vogel d8f168cd39 Fix Windows smoke 14e + soak latency threshold
- Phase 14: copy binary with .exe suffix on Windows (was creating
  non-.exe copy that uninstall didn't remove)
- Phase 14e: check both .exe and non-.exe paths
- Soak latency: exclude index_repository from max query latency
  (indexing 377 files is legitimately slow on Windows/MSYS2)
2026-03-26 10:34:00 +01:00
Martin Vogel 5ca369f313 Fix Windows smoke: skip OpenCode/Aider when binary not on PATH 2026-03-25 23:55:39 +01:00
Martin Vogel 14a197c165 Fix ALL MSYS2 python3 path issues: pipe via cat for every JSON read 2026-03-25 23:39:56 +01:00
Martin Vogel 331b4c4dfb Fix all Windows path comparisons: path_match helper with basename fallback 2026-03-25 23:22:57 +01:00
Martin Vogel c0de9ff5a4 Weekly soak: run Sunday 2am UTC instead of nightly 2026-03-25 22:58:05 +01:00
Martin Vogel b568884e4a Fix MSYS2 python3 path issue: pipe files via cat instead of open()
MinGW python3 is a native Windows binary that doesn't understand
POSIX paths like /tmp/foo.json. Piping file content through cat
(which runs in MSYS2 bash and handles path translation) to python's
stdin avoids the issue entirely.

Fixes Windows smoke test 8a and soak baseline collection.
2026-03-25 22:48:31 +01:00
Martin Vogel 6d4d3246ad Fix Windows smoke 8a: basename comparison + debug output for path mismatch 2026-03-25 22:30:54 +01:00
Martin Vogel adb14ee245 Soak: enforce RSS slope only for 30+ min runs (10-min too noisy)
Investigation: macOS arm64 grew 1MB (43→44MB) but slope was 1123
KB/hr. Linux amd64 grew 3MB (25→28MB) but slope was only 424 KB/hr.
The linear regression fits noise on short runs — small timing
fluctuations produce wildly different slopes on nearly flat data.

For 10-min quick soak: use RSS ceiling (200MB) + ratio (3.0x) +
FD drift + idle CPU. Slope is still reported but not enforced.
For 30+ min runs: slope enforcement at 500 KB/hr (enough samples
for reliable regression).
2026-03-25 21:17:56 +01:00
Martin Vogel 47592c6927 Soak: enhanced RSS leak detection with first/last ratio check 2026-03-25 16:16:07 +01:00
Martin Vogel aa25f73adb Soak test gaps: 200-file fixture, Windows, snapshots, ASan build
- Test project: 377 files (80 Python + 40 Go + 40 TSX + configs)
  instead of 5 files. RSS baseline now ~47MB (real workload).
- Snapshots every 10s (was 30s) — 7+ data points in 1-min run.
- Reindex every 2min compressed (was 5min) — more cycles per run.
- heap_committed fallback: use RSS when mimalloc reports 0.
- Windows soak: added to quick soak matrix (MSYS2 + python3 + git).
- ASan soak: builds with -fsanitize=address (was building release).
- Collect snapshot with single python3 call (was 6 separate calls).
2026-03-25 15:52:28 +01:00
Martin Vogel 3a457d9458 Fix smoke: Windows .exe binary name, UI variant archive fallback 2026-03-25 15:38:36 +01:00
Martin Vogel b6801295f2 Fix soak test: route queries through MCP server (not CLI) for real metrics 2026-03-25 15:33:54 +01:00
Martin Vogel dbd543a966 Add soak test suite: diagnostics + compressed workload + CI jobs
CBM_DIAGNOSTICS=1 writes /tmp/cbm-diagnostics-<pid>.json every 5s.
scripts/soak-test.sh: compressed workload + crash recovery + analysis.
CI: soak_level input (full/quick/none) on dry-run + release.
MCP query timing via cbm_diag_record_query().
2026-03-25 12:38:01 +01:00
Martin Vogel 7d640081e0 UI smoke: verify HTML content in GET / and JSON-RPC in POST /rpc 2026-03-25 10:48:40 +01:00
Martin Vogel 6300feb70c Fix smoke tests: variant detection, Windows deps, UI reachability
- Phase 14: detect UI vs standard variant from HTTP server contents
  instead of hardcoding --standard (fixes UI smoke failure)
- Windows smoke: install zip + coreutils (sha256sum) in MSYS2
  (fixes exit code 127)
- Phase 15: UI HTTP server reachability test — verifies root returns
  200 and /rpc accepts POST (skips gracefully for non-UI builds)
- Fix switch fallthrough in release.yml (same MSYS2 deps)
2026-03-25 10:45:58 +01:00
Martin Vogel abe319b46c Real E2E update/uninstall + CBM_DOWNLOAD_URL support
Add CBM_DOWNLOAD_URL env var to cbm_cmd_update and checksum
verification — allows E2E testing against local HTTP server.

Phase 14: runs actual update --standard -y against local server,
verifies binary replaced, agent configs refreshed (stale path
updated), then real uninstall -y verifies binary removed and
configs cleaned.

Phase 13: add PATH setup verification. Non-interactive stdin:
isatty() prevents silent hangs.
2026-03-24 23:14:33 +01:00
Martin Vogel da7638c651 Prevent silent hangs on non-interactive stdin
Add isatty() checks to prompt_yn() and update variant chooser.
When stdin is not a terminal and no -y/-n or --standard/--ui flag
is provided, print a clear error and exit instead of hanging on
fgets(). Prevents agents from silently blocking when running
install/update programmatically.

Add smoke test 9b-9: verify non-interactive update fails cleanly.
2026-03-24 23:14:33 +01:00
Martin Vogel 8951647d3e Fix remaining install/update gaps + in-memory zip extraction
Install command:
- Add cbm_kill_other_instances() to kill stale MCP servers
- Add cbm_macos_adhoc_sign() to sign binary if placed unsigned

Update command:
- Replace skills-only reinstall with full cbm_install_agent_configs()
- Replace external unzip with cbm_extract_binary_from_zip() via zlib

Refactor: extract 10-agent config loop into cbm_install_agent_configs()
called by both install and update.

New: cbm_extract_binary_from_zip() — in-memory zip extraction with
stored + deflate support, path traversal rejection, bounds checks.
4 unit tests. Smoke: add install.ps1 E2E for Windows.
2026-03-24 23:14:33 +01:00
Martin Vogel 006e6dbf20 Add install scripts, CI pre-signing, download E2E smoke tests
install.sh: one-liner for macOS/Linux — detects OS/arch (Rosetta-
aware), downloads release, verifies checksum, extracts, signs on
macOS, runs install -y for all 10 agents. Supports --ui flag and
CBM_DOWNLOAD_URL env var for testing.

install.ps1: one-liner for Windows — Invoke-WebRequest + Expand-
Archive + Unblock-File (strips MOTW), installs to %LOCALAPPDATA%,
adds to user PATH via [Environment]::SetEnvironmentVariable.

CI pre-signing: add codesign --sign - step for macOS builds in
both dry-run.yml and release.yml, before archiving. Release
binaries now ship pre-signed.

Phase 12 smoke tests: real HTTP download via local artifact server,
checksum verification, archive extraction, binary verification.
Runs only when SMOKE_DOWNLOAD_URL is set (CI provides it).

Phase 13 smoke tests: install.sh E2E — runs full script with local
URL + isolated HOME, verifies binary placed, signed, runs, and
agent configs created.

CI HTTP server: smoke jobs start python3 HTTP server serving the
built binary as a tar.gz/zip archive + checksums.txt. Enables
Phases 12-13 in CI on all platforms.

Update security allowlist: remove system() entry (eliminated),
add cbm_popen for pgrep. Update README with one-liner Quick Start.
2026-03-24 23:14:33 +01:00
Martin Vogel d2451c4fd6 Add comprehensive E2E smoke tests for install/update/uninstall
Phase 8: Agent config install E2E — creates stub environment with
all 10 agent detection dirs, runs install -y with isolated HOME,
verifies exact JSON structure, TOML content, hook format, skills,
and merge-not-overwrite behavior for every agent config.

Phase 9: Agent config uninstall E2E — verifies complete removal of
all MCP entries, hooks, instructions while preserving user's existing
config keys. Adversarial tests: idempotent double install, uninstall
without prior install, corrupt JSON/TOML handling, double uninstall.

Phase 10: Platform binary security — macOS: codesign verify, strip
signature, SIGKILL on unsigned arm64 (exit 137), re-sign + verify.
Linux/Windows: verify unsigned binary runs without signing.

Phase 11: Process kill — start MCP server, verify running, kill,
verify gone.

Phase 14: Update flow — binary replacement with signing, read-only
binary edge case, platform-specific verification.

Fix cbm_find_cli: add S_IXUSR check for hardcoded path search
(was missing, only checked for PATH-based search).
2026-03-24 23:14:33 +01:00
Martin Vogel c00723e5c8 Require project param on all MCP tool calls
Make project a required parameter for all query tools (search_graph,
query_graph, trace_call_path, get_code_snippet, get_graph_schema,
get_architecture, search_code, index_status, detect_changes,
manage_adr, ingest_traces). Removes implicit fallback to session
project or last-opened store.

When project is missing or not found, return error with list of
available indexed projects so agents can self-correct.

Rename delete_project param from project_name to project for
consistency. Fix smoke test trace_call_path depth param name
(max_depth -> depth).
2026-03-24 13:38:25 +01:00
Martin Vogel f24475ca4a Add simulated binary replacement to smoke tests (Phase 6e)
Tests the update command's replacement flow without network calls:
copy binary as "downloaded" version, unlink-then-replace the
"installed" version, verify replaced binary runs --version.
Also tests read-only binary replacement edge case (#114).
2026-03-23 22:02:51 +01:00