Commit Graph
5251 Commits
Author SHA1 Message Date
Martin Vogel 5830d284c5 Merge pull request #2896 from DeusData/fix/hermes-remover-empty-hooks
fix(cli): accept the emptied hooks: {} mapping in the Hermes hook editor
2026-11-03 18:08:22 +01:00
Martin Vogel 464bfb53ec Merge pull request #2878 from DeusData/dependabot/github_actions/actions/download-artifact-8.0.2
build(deps): bump actions/download-artifact from 8.0.1 to 8.0.2
2026-11-03 18:08:14 +01:00
Martin Vogel 190abae96f Merge pull request #2389 from harshitaajoshi/fix/php-inline-html-2000
fix(extract): parse PHP past inline HTML so symbols after ?> reach the graph (#2000)
2026-11-03 07:01:29 +01:00
Martin Vogel 35b50b9ca0 Merge branch 'main' into dependabot/github_actions/actions/download-artifact-8.0.2 2026-11-03 04:28:16 +01:00
Martin Vogel d681c37d37 Merge branch 'main' into fix/hermes-remover-empty-hooks 2026-11-03 03:46:36 +01:00
Martin Vogel 5689ea54ce Merge pull request #1561 from tmonestudio/codex/bt-240-truthful-index-freshness
feat(mcp): report truthful index freshness from checkout evidence
2026-11-03 03:04:02 +01:00
Martin Vogel 334a408b63 Merge pull request #2198 from astandrik/fix/1696-bench-runtime-isolation
fix(test): isolate benchmark harness daemon runtimes
2026-11-03 01:51:49 +01:00
Martin Vogel 08b84e4011 Merge origin/main into fix/php-inline-html-2000
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-11-03 01:40:29 +01:00
Martin Vogel b461b9137f Merge pull request #2781 from DeusData/dependabot/github_actions/actions/upload-artifact-7.0.2
build(deps): bump actions/upload-artifact from 7.0.1 to 7.0.2
2026-11-03 01:40:22 +01:00
Martin Vogel 8ae04f4bd1 Merge pull request #2424 from mvanhorn/fix/1642-python-constructor-calls-init
fix(python): resolve ClassName() calls to __init__
2026-11-03 01:17:11 +01:00
Martin Vogel fabc2b07f8 Merge pull request #1711 from benrfairless/feat/ruby-lsp-per-file
feat(lsp): add the Ruby per-file resolver
2026-11-03 00:57:38 +01:00
Martin Vogel 2921415586 Merge pull request #1430 from vitalNohj/fm/cbm-worktree-ignore-1
feat(config): add ignore_worktrees to skip linked git worktrees
2026-11-02 21:59:10 +01:00
Martin Vogel c1f30fdcc3 Merge origin/main into codex/bt-240-truthful-index-freshness
Second maintainer refresh of #1561 (truthful index_status freshness),
onto main 9c19b5dd, after the fix-up that keeps the indexed checkout in
its own index_checkout table (a0d0521f). The first refresh is b44a22ca.

Five files conflicted; each is resolved as main plus the branch change:

- src/pipeline/pipeline.c and src/pipeline/pipeline_incremental.c (two
  sites): main added .unresolved_calls_complete to the coverage-meta
  initializers where the branch added .indexed_checkout_sha. Both fields
  are kept, main first.

- src/store/store.h cbm_coverage_meta_t: main added
  unresolved_calls_complete where the branch added indexed_checkout_sha.
  Both fields are kept, main first.

- src/store/store.c init_schema: main added the unresolved_calls_complete
  column where the branch closed index_coverage_meta and created
  index_checkout. index_coverage_meta keeps main DDL exactly, and the
  index_checkout table follows it.

- src/store/store.c coverage replace: main moved the coverage-meta write
  out of cbm_store_coverage_replace_ex into coverage_write_metadata,
  whose caller owns the transaction and rolls it back on failure. The
  branch wrote or cleared the index_checkout row right after that
  write, so its two calls move into the helper: the upsert path returns
  index_checkout_write(s, project, meta->indexed_checkout_sha), the
  delete path returns index_checkout_write(s, project, NULL).
  index_checkout_write stays where the branch defined it, ahead of the
  new helpers.

- tests/test_store_nodes.c: main added
  store_coverage_shadow_excludes_unresolved_calls and its helper where
  the branch added store_coverage_meta_indexed_checkout_sha_roundtrip_and_rollback.
  Both tests are kept and registered, main first.

src/pipeline/pipeline_internal.h merged without a conflict: main raised
CBM_SEMANTIC_INDEX_VERSION to 13 for Next.js App Router routes, in a
separate hunk from the branch's cbm_pipeline_indexed_checkout_sha
declaration.

No semantic conflicts:

- The branch bumps no version. index_checkout is created by init_schema
  with IF NOT EXISTS and read only when present, so main's semantic
  index version 13 applies unchanged.

- The branch changes no existing function signature, and main changes
  none that the branch calls.

- Every main caller of cbm_store_coverage_meta_get added since the
  merge base, including the new Next.js upgrade test in test_pipeline.c,
  releases the result with cbm_store_coverage_meta_clear exactly once,
  which frees the checkout string. That test passes a shallow copy of
  the result to cbm_store_coverage_replace_ex and never frees the copy
  on its own.

No test call site needed adapting.

Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-11-02 18:55:43 +01:00
Martin Vogel e87a9ff47e Merge origin/main into fix/1642-python-constructor-calls-init
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-11-02 18:51:12 +01:00
Martin Vogel c03e99c54a Merge branch 'main' into dependabot/github_actions/actions/download-artifact-8.0.2 2026-11-02 18:25:22 +01:00
Martin Vogel b076877680 Merge branch 'main' into dependabot/github_actions/actions/upload-artifact-7.0.2 2026-11-02 18:25:19 +01:00
Martin Vogel e8f0f4a289 fix(cli): accept the emptied hooks: {} mapping in the Hermes hook editor
Removing the only Hermes pre_llm_call hook empties the hooks mapping, and
the mapping editor writes an emptied section as hooks: {} - the same
convention it uses for mcp_servers: {}. The hook sequence editor then
refused that file for both upsert and removal, because it required every
parent on the sequence path to be a block mapping header. On a config
where our hook was the only entry under hooks, install -> uninstall ->
install exited 1, and a repeated uninstall did too.

An exact empty flow mapping on a parent of the sequence path is now read
as that empty mapping, mirroring how the mapping-entry editor already
treats section: {}. Removal is a byte-identical no-op, and upsert expands
the header in place, keeping its comment, the line endings and every
other byte, so a reinstall lands back on the first install byte for
byte. The sequence key itself holding a mapping, any other flow value,
and content nested under the inline mapping stay refused. Hooks written
by the user and every foreign key are left untouched.

Found while finishing #1862: its persisted hook opt-out runs this remover
on every later install, so every Hermes user whose only hook was ours
would have hit the refusal on each install after the first.

Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-11-02 18:23:18 +01:00
Martin Vogel a0d0521fcb fix(store): keep the indexed checkout outside the digested tables
index_coverage_meta is one of the tables the graph digest pins column
by column, so the new indexed_checkout_sha column made the digest
reject every live store with a schema error: the live-schema
compatibility test failed, and test-impact, which digests the graph it
builds for HEAD, fell back to running every test for every change.

Record the checkout in a table of its own instead: index_checkout
(project primary key referencing projects ON DELETE CASCADE,
indexed_checkout_sha NOT NULL). A checkout is source identity, which
the graph digest deliberately does not bind, and the store already
keeps other per-project data (doc_link_*, observed_*) outside the
digested tables. index_coverage_meta keeps exactly the shape the digest
expects, so the digest needs no change and no version bump, and a new
table needs no migration of existing databases.

The row is written and cleared in the same coverage transaction, so a
failed replace keeps the previous identity, and it is removed with its
project. The store API is unchanged: cbm_coverage_meta_t carries
indexed_checkout_sha as before. Read-only opens of databases without
the table report no identity, as before.

store_graph_digest_indexed_checkout_identity_is_not_bound writes a
store through the real coverage API with and without a checkout SHA
and asserts that it still digests and that the SHA leaves the digest
unchanged.

Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-11-02 18:12:22 +01:00
Martin Vogel a7a9f27fae Merge origin/main into fix/1696-bench-runtime-isolation
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-11-02 18:10:57 +01:00
Martin Vogel a508219299 Merge origin/main into feat/ruby-lsp-per-file
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-11-02 18:09:59 +01:00
Martin Vogel ff74ab0982 Merge origin/main into fix/php-inline-html-2000
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-11-02 18:09:51 +01:00
Martin Vogel 9c19b5dd9e Merge pull request #2245 from lorenzozanee/fix/termux-portable-guard
fix(install): reject unsupported Android portable installs
2026-11-02 18:08:10 +01:00
Martin Vogel afe57369ee Merge pull request #2879 from DeusData/dependabot/github_actions/actions/setup-python-7.1.0
build(deps): bump actions/setup-python from 7.0.0 to 7.1.0
2026-11-02 18:08:02 +01:00
Martin Vogel c80a256999 Merge pull request #2207 from AmirF194/fix/lifetime-lock-probe-drops-held-lock
fix(daemon): stop the lifetime-lock probe from dropping a held lock
2026-11-02 18:07:53 +01:00
Martin Vogel 7a9b1cb0d3 Merge pull request #2838 from halindrome/perf/index-worker-priority
perf(index): run supervised index workers at below-normal CPU priority
2026-11-02 18:07:41 +01:00
Martin Vogel f78620fe6c Merge pull request #2747 from petterip/feat/nextjs-app-router-routes
feat(extraction): route Next.js App Router handlers (#759)
2026-11-02 18:07:31 +01:00
Martin Vogel 141b25af7b fix(mcp): do not shadow cache_dir() in the ignore_worktrees reader
cppcheck 2.20 (the CI version) reports shadowFunction: the local
cache_dir in cbm_mcp_ignore_worktrees_runtime_enabled() shadows the
static cache_dir() helper in mcp.c. Rename the local to store_dir; no
behavior change.

Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-11-02 02:16:53 +01:00
Martin Vogel 1976986f4b Merge origin/main into fm/cbm-worktree-ignore-1
Brings the branch up to main a5b248f47. Eight files conflicted, each a
same-spot insertion where main and this branch added lines next to the
same anchor. Each resolves to the main version plus the change of this
branch:

- src/cli/cli.h, src/cli/cli.c: CBM_CONFIG_IGNORE_WORKTREES and its
  CONFIG_KEYS row next to the new doc_candidates key.
- src/mcp/mcp.c: the index_worktree schema property next to the new
  doc_candidates property.
- README.md, docs/CONFIGURATION.md: the ignore_worktrees line and table
  row next to the rewritten auto_watch entries and the new
  doc_candidates and watch_non_git rows.
- src/git/git_context.c: the env-isolation comment after the new debug
  stage marker, directly above cbm_popen_git.
- src/cli/hook_augment.c: the new SubagentStart cli_hint ahead of the
  parent-graph check of this branch.
- tests/test_mcp.c: both RUN_TEST blocks; main already includes
  str_util.h.

Per file, the lines changed against main equal the changes of this
branch against the merge-base.

Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-11-02 02:07:22 +01:00
Martin Vogel 04ed0240e9 docs(config): state how ignore_worktrees treats subdirectories
The review of 2026-10-01 asked for this to be a stated decision rather
than a side effect. Detection walks up from the given path to the
nearest .git entry, so a subdirectory of a linked worktree is treated
as that worktree: index_repository on it is refused, and a session root
or hook working directory inside it is handled the same way. The walk
stops at the first .git; outside any checkout it runs to the filesystem
root one directory at a time. None of it runs while the key is off.

Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-11-02 02:04:21 +01:00
Martin Vogel 77310d5f6f fix(cli): keep the hook default path untouched while ignore_worktrees is off
The lifecycle hook now reads ignore_worktrees first and does nothing
else for it while the key is off; the project lookup is then the one
the hook did before the key existed.

- cbm_mcp_ignore_worktrees_runtime_enabled() replaces
  cbm_mcp_server_attach_runtime_config(). It never attaches a store to
  the server, which may be the daemon session server. A server with a
  store answers from it. Otherwise the runtime store is opened only to
  read this key, and only when it already exists, so a hook event never
  creates _config.db.
- cwd canonicalization, the linked-worktree probe and the parent-graph
  check moved into ha_resolve_project_ignoring_worktrees(), which runs
  only when the key is on.

Test cli_hook_ignore_worktrees_default_off_does_no_worktree_work was red
on the previous head (a default-off event created _config.db). It also
pins, through a test-API counter, that neither an absent store nor a
store without the key reaches the worktree gate, and that the key on
reaches it once. mcp_ignore_worktrees_runtime_read_leaves_server_and_store_alone
replaces the test of the removed helper.

Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-11-02 02:04:15 +01:00
Martin Vogel faf25ee4fa fix(config): drop the fuzz-link and Cypher hunks from the worktree change
The review of 2026-10-01 asked to split these out of the ignore_worktrees
change. Neither belongs to it, and both are already on main in another
form, so this restores the three files to the branch merge-base:

- Makefile.cbm: main links cbm-fuzz with -fsanitize-link-c++-runtime.
- src/cypher/cypher.c and tests/test_cypher.c: main frees a partially
  parsed MATCH pattern since 70543ba82, with its own regression test
  cypher_parse_error_frees_partial_pattern.

Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-11-02 02:04:05 +01:00
Martin Vogel 3f12a3f24b Merge branch 'main' into dependabot/github_actions/actions/upload-artifact-7.0.2 2026-11-02 01:44:30 +01:00
Martin Vogel 760d73c91b Merge origin/main into fix/1696-bench-runtime-isolation
Brings #2198 (benchmark harness runtime isolation, #1696) up to date
with main a5b248f4.

No conflicts. Of the files this branch touches, main changed only
scripts/test.sh since the merge base 8530c8cd: it adds Step 5-alloc
(production allocator contract), far from this branch's Step 0i3,
which is unchanged. scripts/test-runtime.sh, which the harnesses and
their contract test source, is unchanged on main. No caller of either
harness outside docs/EVALUATION_PLAN.md exists on main.

Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-11-02 00:08:59 +01:00
Martin Vogel b9a186db47 test(bench): cover setup failure, refused daemon start and refused stop
Three more cases in the benchmark runtime isolation contract, each RED
against the harness without its fix:

- a stale runtime-root.txt is gone after a run that fails during setup
  (a repository path that does not exist);
- with the keep flag and a `daemon stop` that refuses, the run fails,
  writes no handoff, keeps its root and prints the refusal; the test
  removes that root itself, before any verdict, so a failing assertion
  leaks nothing;
- a refused `daemon start` fails both harnesses, prints the cause and
  leaves no root behind.

The fixture refuses the start on stderr and the stop on stdout, the
channel the product uses for a busy refusal.

Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-11-02 00:06:52 +01:00
Martin Vogel 32f60a4e8d docs(eval-plan): stop clearing the live cache before an isolated run
Section 7 still began with rm -f ~/.cache/codebase-memory-mcp/*.db.
Every index in the loop now lands in a run-private cache (#1696), so
that line no longer made any run colder; it only deleted the indexes in
the live store of the operator. Dropped, and the comment above it now
names only what the setup still does.

Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-11-02 00:06:52 +01:00
Martin Vogel 78bf6a2745 fix(test): hand over a kept benchmark runtime only after its daemon stopped
With CBM_BENCH_KEEP_RUNTIME=1, bench_finish ran `daemon stop` with its
output and exit status discarded and wrote runtime-root.txt regardless.
`daemon stop` refuses while a committed client still uses the daemon and
fails when the daemon does not answer; the handoff then promised a
stopped daemon that was still running.

A refused stop now prints the explanation of the product, writes no
handoff, keeps the root without cleaning it up (the daemon may still be
using it) and exits non-zero. A stop with nothing to stop still exits 0,
so a clean run is unaffected.

Section 7 step 8 of the evaluation plan follows the same rule: the kept
root is removed only if its daemon stopped, and is kept with a message
otherwise.

Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-11-02 00:06:52 +01:00
Martin Vogel b9851700a4 fix(test): surface why a benchmark daemon did not start
Both harnesses discarded the output of `daemon start`, so a refused
start was reported only as "private daemon did not start", the symptom
without its cause. The output now goes to a run-private file next to the
index stderr, the shape both scripts already use for the index call, and
is printed under "--- daemon start output ---" when the start fails.

Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-11-02 00:06:52 +01:00
Martin Vogel 14b8da00c3 fix(test): drop a stale benchmark handoff before setup can fail
benchmark-index.sh removed the runtime-root.txt of an earlier run only
after the repository path, the private runtime and the temp directory had
been set up. A run that failed in one of those steps exited non-zero but left
the previous handoff in the reused results directory, and section 7 of
the evaluation plan sources that file unconditionally, so the graph
session would be pointed at a root that step 8 has already removed.

The results directory is now created and the stale handoff removed right
after argument parsing, before any setup step that can fail.

Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-11-02 00:06:52 +01:00
Martin Vogel df92904bcb Merge branch 'main' into dependabot/github_actions/actions/download-artifact-8.0.2 2026-11-01 23:20:26 +01:00
Martin Vogel c04e322d61 Merge branch 'main' into dependabot/github_actions/actions/setup-python-7.1.0 2026-11-01 23:20:24 +01:00
Martin Vogel a5b248f472 Merge pull request #2261 from tamerbak/docs/contributor-check-prerequisites
Docs/contributor check prerequisites
2026-11-01 23:19:34 +01:00
Martin Vogel 7a7ecb7356 test(install): keep the Android guard test off the network
Point CBM_DOWNLOAD_URL, the documented download-base override in
install.sh, at a closed loopback port. If a curl stub were ever missed
on some leg, the download would then fail locally instead of fetching
a real release.

Check that the uname stub is the one PATH resolves before running
install.sh. Otherwise the test would quietly exercise the real host
instead of an Android one and prove nothing.

Refs #1202

Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-11-01 23:02:46 +01:00
Martin Vogel 9f278b7ed3 Merge pull request #2880 from DeusData/dependabot/github_actions/ossf/scorecard-action-2.5.0
build(deps): bump ossf/scorecard-action from 2.4.4 to 2.5.0
2026-11-01 22:58:22 +01:00
Martin Vogel 79f674efe0 Merge origin/main into fix/termux-portable-guard
Brings the branch up to current main (it was 2061 commits behind) so
the new Step 0x2 runs inside the current scripts/test.sh. No conflicts.

Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-11-01 22:44:24 +01:00
Martin Vogel 8b2b0d769f fix(install): say that Termux is not a supported platform yet
The guard told users to build from source with scripts/build.sh in
Termux, which reads as a supported path. Source builds under Termux
still have open problems tracked in #1202, so the message now says
why the portable binary cannot run there and that a source build may
work but is not supported yet, pointing at #1202.

The test still matches Android/Termux in the new message.

Refs #1202

Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-11-01 22:43:59 +01:00
Martin Vogel 1fc70c2024 test(install): run the Android guard test as Step 0x2 of scripts/test.sh
scripts/test.sh lists every shell contract test explicitly and does
not glob tests/, so an unlisted test never ran on any leg. Register
tests/test_install_android_guard.sh as Step 0x2, right after Step 0x,
in the same two-line shape as its neighbours.

Give the two PATH stubs (uname, curl) the same shebang every other
stub under tests/ uses, so they are proper executables on every leg
instead of relying on the shell fallback for files without one.

Refs #1202

Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-11-01 22:43:58 +01:00
Martin Vogel 17415f6a38 test(install): rename the Android guard test to the test_*.sh convention
Every shell contract test under tests/ is named test_*.sh with
underscores. A pure rename, so history and blame follow the file.

Refs #1202

Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-11-01 22:43:58 +01:00
Martin Vogel 9e0159e3e4 Merge origin/main into fix/1642-python-constructor-calls-init
Brings the branch up to date with main edc2301b. Main only changed
CI configuration since the branch base (CodeQL action, actions/attest
and msys2/setup-msys2 pins, Dependabot grouping); no conflicts.

Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-11-01 21:37:03 +01:00
Martin Vogel e8cb85cf0f Merge origin/main into fix/php-inline-html-2000
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-11-01 21:30:01 +01:00
Martin Vogel 616ba4111f Merge origin/main into perf/index-worker-priority
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-11-01 21:29:54 +01:00