137 Commits
Author SHA1 Message Date
Martin Vogel d5742aab90 ci(codeql): revert CodeQL gate hardening from 27e640b
Reverts the CodeQL portion of 27e640b ('fix(mcp,ci): harden
get_architecture serialization + CodeQL gate'). Leaves the mcp.c +
test_mcp.c changes (NULL-coercion, clusters/services serialization,
extract_text_content fix, regression test) intact.

Restored to the pre-27e640b state:
  - drop 'jq' from build-deps install line
  - drop 'queries: +./codeql' from codeql-action/init (no ./codeql
    custom-query directory exists in this repo)
  - drop 'id: analyze' and 'output: codeql-results' on analyze step
  - drop the SARIF-parsing 'Fail on CodeQL error-level findings' step

CI workflow changes need their own design discussion per CONTRIBUTING.md
('Project configuration / CI workflows' is in the explicit-approval list);
the gate hardening landed bundled with an unrelated bug fix. Splitting it
out so the upstream MCP fix stays clean and any future CodeQL gate work
can be its own focused PR.
2026-05-09 16:52:11 +02:00
Martin Vogel 27e640b3b0 fix(mcp,ci): harden get_architecture serialization + CodeQL gate
Follow-up to #281 (handle_get_architecture) plus a CodeQL workflow
upgrade developed in parallel; bundling into one commit because the
test suite had to land alongside both.

mcp.c — handle_get_architecture
- NULL-coerce every const-char* field in the architecture sections
  via `x ? x : ""`, matching the rest of mcp.c (search_graph, etc.).
  Without this, a NULL field becomes a missing JSON key instead of
  an empty string; yyjson_mut_obj_add_str returns false on NULL and
  silently no-ops, so an inconsistent omission could surprise callers.
- Serialize two more architecture aspects that #281 left on the
  floor: services (cbm_service_link_t: from/to/type/count) and
  clusters (cbm_cluster_info_t: id/label/members/cohesion plus the
  top_nodes / packages / edge_types string arrays). The store-side
  computation populates these for aspects=["all"] / explicit names,
  so dropping them in the serializer was data loss.

tests/test_mcp.c
- New tool_get_architecture_emits_populated_sections regression test.
  Uses a minimal inline fixture (single Function node tagged with
  "is_entry_point": true) since arch_entry_points reads that flag
  out of properties_json. Asserts the response contains both an
  "entry_points" array and the function name — neither would appear
  before #281 because handle_get_architecture never called
  cbm_store_get_architecture.
- extract_text_content drilled too shallow: it pulled "content" only
  from the JSON root, so it worked for cbm_mcp_handle_tool but
  silently fell through to the raw response for cbm_mcp_server_handle
  (where content lives under .result.content). Added a fallback that
  checks .result.content; both unwrappers tested by existing fixtures.

ci(codeql)
- Run on pull_request to main, not just push; surfaces findings on
  the PR instead of after merge.
- Pull custom queries from ./codeql via `queries: +./codeql`.
- Capture SARIF output and fail the job on any error-level finding,
  using jq to enumerate rule id, file:line, and message text in the
  GitHub Actions error annotation. Warnings are still reported as
  before; only errors block.

Full suite: 2842 passed, 0 failed.
2026-05-09 16:37:53 +02:00
dependabot[bot] d27f4aa8c6 ci(deps): bump actions/setup-node from 6.3.0 to 6.4.0 (#289)
Patch bump (PR title was rebased to 4.2.0->6.4.0 originally; current diff is 6.3.0 -> 6.4.0).
2026-05-09 01:27:26 +02:00
dependabot[bot] d70c71776c ci(deps): bump msys2/setup-msys2 from 2.31.0 to 2.31.1 (#268)
Patch bump applied across _build.yml, _smoke.yml, _soak.yml, _test.yml.
2026-05-09 01:27:14 +02:00
dependabot[bot] 3bf38c962d ci(deps): bump github/codeql-action from 4.35.1 to 4.35.2 (#270)
Patch bump for codeql-action across codeql.yml and scorecard.yml.
2026-05-09 01:26:58 +02:00
dependabot[bot] 5da650ff74 ci(deps): bump actions/cache from 5.0.4 to 5.0.5 (#269)
Patch bump.
2026-05-09 01:26:47 +02:00
dependabot[bot] f81065d3fb ci(deps): bump softprops/action-gh-release from 2.6.1 to 3.0.0 (#267)
v3.0.0 moves the action runtime from Node 20 to Node 24. GitHub-hosted runners (which this repo uses) already support the Node 24 Actions runtime, so the upgrade is transparent.
2026-05-09 01:26:27 +02:00
Dustin Obrecht 2d00c4a337 fix: GitHub Actions shell injection in _build.yml (#249)
Replace direct `${{ ... }}` interpolation in `run:` steps of `.github/workflows/_build.yml` with `env:` blocks per GitHub's hardening guide. Every workflow input (`inputs.version`) and matrix value (`matrix.cc`, `matrix.cxx`, `matrix.goos`, `matrix.goarch`, `matrix.arch`) now flows into the shell through a named environment variable rather than being textually spliced into the script.

Pattern applied uniformly across the 6 flagged steps plus the archive steps that used `${{ matrix.* }}` in tar filenames. The values become opaque shell variables on expansion, so attacker input becomes a literal argv entry rather than interpreted shell code. The if/else form on `$VERSION` avoids word-splitting pitfalls of conditional arg construction.

semgrep `run-shell-injection` findings: 6 → 0. Behaviour preserved — same build.sh invocations, same artefact names, same conditional version handling.

Reference: https://securitylab.github.com/research/github-actions-untrusted-input/

Closes #247.
2026-05-09 00:40:26 +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 4fdcdd4239 fix(security): close open scanner alerts
Dependabot/CodeQL #33 — postcss XSS GHSA-qx2v-qp2m-jg93:
  npm audit fix in graph-ui (8.5.8 -> 8.5.14, above the <8.5.10 vuln range)

CodeQL #39 — TOCTOU race in artifact.c ensure_gitattributes():
  Replace stat() + fopen() with open(O_WRONLY|O_CREAT|O_EXCL).
  Atomic create-only-if-absent closes the check-vs-write window.
  Falls through to merge driver setup if file already exists.

CodeQL #55 — pip install not pinned in release.yml:
  Pin build==1.3.0 and twine==6.2.0. Comment explains why
  --require-hashes is not used (transitive-deps overhead).

Dismissed (won't-fix):
  - #56 contents: write — required for 'gh release edit --draft=false';
    no narrower permission exists.
  - #54-51 Crystal grammar warnings — vendored upstream code.
  - #50-40 Agda grammar warnings — vendored upstream code.
2026-05-05 00:51:52 +02:00
Martin Vogel 6aab9d5693 fix(release): atomic publish — un-draft GH release only after registries succeed
Previously the un-draft step ran inside the verify job, before
publish-registries. If npm or PyPI publish failed, the GitHub release
was already live but the wrappers were not — half-shipped state.

Move the un-draft into a new publish-final job that needs both
[verify, publish-registries]. If any registry fails, the GH release
stays in draft and the run can be re-tried with replace=true.
2026-05-04 23:21:26 +02:00
Martin Vogel 4cdc2dc9f3 feat(release): auto-publish npm and PyPI wrappers
Add publish-registries job to release.yml that runs after verify
(release published, VirusTotal table appended). Publishes:

- pkg/npm via 'npm publish --access public --provenance'
- pkg/pypi via 'twine upload' (sdist + wheel from hatchling)

Both wrappers fetch the binary at install time, so a version bump is
the only per-release change needed. Bumped to 0.6.1.

Requires NPM_TOKEN and PYPI_TOKEN repo secrets.
2026-05-04 23:17:51 +02:00
DeusData 68dd64ce23 Bump actions/upload-artifact from 7.0.0 to 7.0.1
Bump actions/upload-artifact from 7.0.0 to 7.0.1
2026-04-15 22:40:10 +01:00
DeusData ae3e1645e9 Bump actions/attest-sbom from 2.4.0 to 4.1.0
Bump actions/attest-sbom from 2.4.0 to 4.1.0
2026-04-15 22:40:07 +01:00
DeusData 0a07187bbd Fix VirusTotal links to use binary hashes instead of archive hashes
checksums.txt contains hashes of .tar.gz/.zip archives; VirusTotal
indexes the extracted binaries. Updated README table and badge to use
correct binary SHA-256 hashes for v0.6.0. Updated release.yml to hash
extracted binaries from the binaries/ directory for future releases.
2026-04-12 20:27:54 +01:00
DeusData fb738e4cb3 Add VirusTotal scan links, SLSA badge, and Security section to README
- Adds VirusTotal (0/72) and SLSA Level 3 badges to the header
- Adds Security section with per-binary VirusTotal scan links for v0.6.0
- Adds step in release.yml to auto-append a Security Verification table
  with per-binary VirusTotal links to every release's notes going forward
2026-04-12 19:18:29 +01:00
dependabot[bot] fb4c0d0783 Bump actions/upload-artifact from 7.0.0 to 7.0.1
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 7.0.0 to 7.0.1.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/bbbca2ddaa5d8feaa63e36b76fdaad77386f024f...043fb46d1a93c77aae656e7c1c64a875d1fc6a0a)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-version: 7.0.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-11 05:42:48 +00:00
dependabot[bot] b8db37326c Bump actions/attest-sbom from 2.4.0 to 4.1.0
Bumps [actions/attest-sbom](https://github.com/actions/attest-sbom) from 2.4.0 to 4.1.0.
- [Release notes](https://github.com/actions/attest-sbom/releases)
- [Changelog](https://github.com/actions/attest-sbom/blob/main/RELEASE.md)
- [Commits](https://github.com/actions/attest-sbom/compare/bd218ad0dbcb3e146bd073d1d9c6d78e08aa8a0b...c604332985a26aa8cf1bdc465b92731239ec6b9e)

---
updated-dependencies:
- dependency-name: actions/attest-sbom
  dependency-version: 4.1.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-11 05:42:37 +00:00
Martin VogelanddLo999 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 2b28c45149 Bump Actions: download-artifact v8.0.1, attest-sbom v2, cosign v4.1.1, msys2 v2.31.0
Applies dependabot PRs #202, #203, #204, #205 directly (PRs conflict
with restructured workflow files).
2026-04-06 17:43:13 +02:00
Martin Vogel 4517411fdd Add security audits to portable Linux smoke tests
Portable binaries now get the same security-strings, security-install,
and security-network audits as regular Linux/macOS builds. Closes gap
where the portable (musl static) binary was smoke-tested but not
security-audited.
2026-04-06 16:34:32 +02:00
Martin Vogel 2350240c1d Decouple security gate from pipeline, fix clang-format-20 and Linux agent detection
Workflow:
- Split _lint.yml (cppcheck + clang-format) from _security.yml
  (security-static + codeql-gate)
- Dry Run: security runs as independent island, not blocking
  lint → test → build → smoke/soak
- Release: security only blocks final verify step

Fixes:
- pass_semantic_edges.c: typedef hyperplane_row_t avoids function-returning-
  array-pointer syntax that clang-format-20 rejects
- cli.c: Linux agent detection uses home_dir-relative .config/ paths
  instead of cbm_app_config_dir() which ignores the test home_dir
2026-04-06 13:27:43 +02:00
Martin Vogel 613ce403e7 Fix CI lint: use --ci flag to skip clang-tidy (enforced locally via pre-commit)
clang-tidy is platform-dependent and not installed in CI. The pre-commit
hook enforces clang-tidy locally. CI runs cppcheck + clang-format only.
2026-04-02 22:51:11 +02:00
Martin Vogel 43cde32d3d Fix CodeQL alerts: pin Alpine image digest, scope release permissions
- Pin Dockerfile.alpine to SHA digest (PinnedDependenciesID)
- Narrow workflow-level permissions to contents:read (TokenPermissionsID)
- Elevated permissions only on release-draft and verify jobs
2026-04-02 22:42:44 +02:00
Martin Vogel 0eba6dff38 Fix portable Linux build: gcc -static on Ubuntu, no Docker
- Portable build uses gcc -static on native Ubuntu runner
- Rename PAGE_SIZE -> CBM_PAGE_SIZE (conflicts with musl limits.h)
2026-04-02 21:39:04 +02:00
Martin Vogel 9662063090 Add Alpine portable as 4th local test platform, fix musl compat
Local test infra now covers 4 platforms:
- Linux arm64 (Ubuntu, ASan+LeakSan)
- Linux portable (Alpine musl, static binary)
- Windows (mingw cross-compile)
- macOS (native)

Fixes:
- Remove sys/unistd.h and sys/poll.h (glibc-only, musl lacks them)
- Add STATIC=1 support to Makefile (appends -static to LDFLAGS)
- CI portable build uses docker run alpine instead of container directive
  (GitHub Actions JS actions break in Alpine containers on ARM64)
2026-04-02 20:28:20 +02:00
Martin Vogel 4f05c64aae Replace Alpine container with musl-tools on Ubuntu for portable builds
Alpine containers on ARM64 runners break GitHub Actions JS-based
actions (checkout, upload-artifact). Use musl-gcc on Ubuntu instead.
2026-04-02 19:41:16 +02:00
Martin Vogel c986b407f8 Add bash to Alpine portable build (scripts use #!/usr/bin/env bash) 2026-04-02 19:10:16 +02:00
Martin Vogel f9106c836a Fix CI job ordering: soak runs after build, parallel with smoke
lint → test → build → smoke
                    → soak
2026-04-02 17:27:46 +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 e582df3194 Convert perf assertions to warnings, add CI job timeout
Shared CI runners are too variable for hard timing thresholds.
Performance is still logged and warns above 15s, but no longer
blocks the test suite. Added 30min timeout on test-unix jobs.
2026-04-02 13:33:43 +02:00
Martin Vogel 7fa3acd0c6 WIP: strict linting + RAM-first pipeline (lint fixes pending) 2026-04-01 23:22:44 +02:00
DeusData 148d951e1a Merge pull request #167 from DeusData/dependabot/github_actions/actions/cache-5.0.4
Bump actions/cache from 4.3.0 to 5.0.4
2026-03-29 11:56:32 +02:00
DeusData 7bc109ee78 Merge pull request #166 from DeusData/dependabot/github_actions/actions/checkout-6.0.2
Bump actions/checkout from 4.2.2 to 6.0.2
2026-03-29 11:56:27 +02:00
DeusData 6d33c10912 Merge pull request #165 from DeusData/dependabot/github_actions/actions/upload-artifact-7.0.0
Bump actions/upload-artifact from 4.6.2 to 7.0.0
2026-03-29 11:56:21 +02:00
DeusData 469ef4e0f5 Merge pull request #164 from DeusData/dependabot/github_actions/actions/attest-build-provenance-4.1.0
Bump actions/attest-build-provenance from 2.4.0 to 4.1.0
2026-03-29 11:56:16 +02:00
dependabot[bot] f71ea61b18 Bump actions/cache from 4.3.0 to 5.0.4
Bumps [actions/cache](https://github.com/actions/cache) from 4.3.0 to 5.0.4.
- [Release notes](https://github.com/actions/cache/releases)
- [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md)
- [Commits](https://github.com/actions/cache/compare/0057852bfaa89a56745cba8c7296529d2fc39830...668228422ae6a00e4ad889ee87cd7109ec5666a7)

---
updated-dependencies:
- dependency-name: actions/cache
  dependency-version: 5.0.4
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-28 05:43:16 +00:00
dependabot[bot] 10eb56900a Bump actions/checkout from 4.2.2 to 6.0.2
Bumps [actions/checkout](https://github.com/actions/checkout) from 4.2.2 to 6.0.2.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v4.2.2...de0fac2e4500dabe0009e67214ff5f5447ce83dd)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: 6.0.2
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-28 05:43:09 +00:00
dependabot[bot] e3ee39f1ec Bump actions/upload-artifact from 4.6.2 to 7.0.0
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4.6.2 to 7.0.0.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/ea165f8d65b6e75b540449e92b4886f43607fa02...bbbca2ddaa5d8feaa63e36b76fdaad77386f024f)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-version: 7.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-28 05:42:56 +00:00
dependabot[bot] 1f8df9d02d Bump actions/attest-build-provenance from 2.4.0 to 4.1.0
Bumps [actions/attest-build-provenance](https://github.com/actions/attest-build-provenance) from 2.4.0 to 4.1.0.
- [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/e8998f949152b193b063cb0ec769d69d929409be...a2bbfa25375fe432b6a289bc6b6cd05ecd0c4c32)

---
updated-dependencies:
- dependency-name: actions/attest-build-provenance
  dependency-version: 4.1.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-28 05:42:49 +00:00
dependabot[bot] c86b7864f0 Bump github/codeql-action from 4.34.1 to 4.35.1
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 4.34.1 to 4.35.1.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/38697555549f1db7851b81482ff19f1fa5c4fedc...c10b8064de6f491fea524254123dbe5e09572f13)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-version: 4.35.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-28 05:42:45 +00:00
Martin Vogel b31d177089 VT gate: all files block equally, no warnings — scripts can contain harmful code too 2026-03-26 13:26:57 +01:00
Martin Vogel 4aa1690022 VT gate: increase timeout to 120 min (was 20 min) 2026-03-26 13:24:53 +01:00
Martin Vogel 3087c2ab27 VT gate: warn (not block) when script files timeout (low VT priority) 2026-03-26 13:21:05 +01:00
Martin Vogel 061ec32fe3 Fix: normalize path separators on ALL platforms + require soak-asan for release 2026-03-26 12:13:48 +01:00
Martin Vogel c0de9ff5a4 Weekly soak: run Sunday 2am UTC instead of nightly 2026-03-25 22:58:05 +01:00
Martin Vogel 38f699b72e Add nightly 4h soak test (scheduled 2am UTC, manual trigger) 2026-03-25 22:09:49 +01:00
Martin Vogel 7074dc2f1b Fix Windows: taskkill self-kill + soak missing build deps
1. taskkill /IM killed the install process itself — now uses
   /FI "PID ne <self>" to exclude own process
2. Windows soak jobs missing clang, zlib, make packages — added
   to all soak-quick-windows and soak-asan-windows MSYS2 installs
3. Both dry-run.yml and release.yml fixed
2026-03-25 21:53:58 +01:00
Martin Vogel 5f9da0ee4a Fix 3 CI failures: Windows .exe path, tre ssize_t, UI archive name
1. Windows install/update: append .exe to binary path on _WIN32
   (was writing empty command to .claude.json)
2. Vendored tre: add ssize_t typedef for Windows (basetsd.h SSIZE_T)
3. Smoke server: copy UI archive under standard name too, so
   install.sh and update --standard work in UI variant smoke tests
2026-03-25 21:33:01 +01:00