Commit Graph
3202 Commits
Author SHA1 Message Date
Martin Vogel dc735c01fb fix(install): migrate v0.10.8 OpenCode agent profiles on upgrade (#2264)
Upgrading from v0.10.8 to v0.11.0 on a machine with OpenCode reported all
three OpenCode subagent profiles as "preserved modified profile" plus an
op=agent_install error each, and the activation stopped ("one or more agent
configurations failed; the published/current executable was kept"), although
nobody had edited those files.

Root cause: #1933 (v0.11.0) added the tool_search / tool_search_regex
permissions to the rendered OpenCode profile. Install and uninstall recognise
a profile as ours only when it matches the current rendering or one of the
known released renderings (the other access mode, the v0.9.1-rc.1 Codex
shape, the pre-tier Verify file). The v0.10.8 OpenCode shape was not in that
set, so cbm_text_migrate_owned_document classified the untouched v0.10.8
files as user-modified. Reproduced end to end: install with the v0.10.8
release binary, then install with v0.11.0/main, into an isolated HOME; the
three profiles are 1729/1880/1910 bytes, the same sizes as in the report.

cbm_render_graph_profile_opencode_v0108() renders the pre-#1933 shape
(both access modes), and install/uninstall now list it as a released
rendering, so those files are upgraded in place and uninstall removes them
as owned. A profile the user actually edited is still preserved. The
released-list assembly that install and uninstall duplicated moves into one
helper, and the two legacy renderers share one implementation (cli.c drops
three raw free sites; the memory-core baseline is tightened 173 -> 170).

The Codex and OpenCode op=mcp_install errors in the same report do not
reproduce from a pristine v0.10.8 config and depend on the reporter's own
config.toml / opencode.json; they are not addressed here.

Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-09-28 00:01:58 +02:00
Martin Vogel 9d65f4cb62 Merge pull request #2362 from knewstimek/pr/windows-mkstemp-errno
fix(windows): preserve mkstemp errors through cleanup
2026-09-27 23:50:03 +02:00
Martin Vogel f4654a7c77 Merge pull request #2373 from DeusData/fix/defs-walk-no-cap
fix(extract): definitions walk stack grows without a ceiling
2026-09-27 23:39:31 +02:00
Martin Vogel b0fe8aef94 Merge pull request #2376 from DeusData/test/watcher-pending-free-held-state
test(watcher): pin the pending-free drain on a held state, not a git probe
2026-09-27 23:34:28 +02:00
Martin Vogel 07eb426c95 test(watcher): wait for the 14th reindex attempt in the sustained-failure test
watcher_sustained_failure_logs_once_issue2015 failed on macos-14 CI with
`failing_index_calls == 13, expected 14`. Its loop ran exactly 14
touch+poll rounds and assumed each one reached the index callback. A poll
whose git probe fails transiently (spawn refused under runner load) is a
fail-closed no-op by design (#937): the baseline stays uncommitted and the
next poll retries. So one refused spawn costs one attempt, and the count
ends at 13. This is the same test race as watcher_unwatch_drains_pending_free,
not a production defect. Holding one exhausted spawn mid-loop with
cbm_subprocess_force_spawn_eagain_for_testing reproduces the CI line
exactly.

The loop now polls until the 14th failed attempt instead of counting
polls. Each poll runs at most one attempt for the single project, so it
stops at exactly 14. A watcher that never reindexes hangs, and the runner
reports that as a failure, never a pass. The log-once contract means the
same thing as before: watcher.index.sustained_failure is emitted only on a
failed index attempt when the streak equals the threshold, so extra no-op
polls cannot add lines. An `==` to `>=` mutation in watcher.c still turns
it red (`sustained_log_hits == 5, expected 1`).

The change is now a dirty worktree instead of a commit. If the baseline
poll itself failed, the old commit would be adopted as the baseline HEAD
and never reindexed, so the wait would never end. The baseline keeps the
dirty signature at "clean known", so a dirty change is seen whenever the
baseline lands. With spawns forced to fail at the baseline poll and again
mid-loop, the test passes after 16 polls for 14 attempts.

Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-09-27 16:06:29 +02:00
Martin Vogel 5df8b0442c Merge pull request #2301 from ivanlinhf/chore/scoop-manifest-0.11.0
chore(scoop): bump packaged manifest to 0.11.0
2026-09-27 16:03:17 +02:00
Martin Vogel 6935df23a9 Merge pull request #1816 from z2250389/codex-z2250389/fix-windows-unicode-git-root
fix(windows): support Unicode repository paths
2026-09-27 16:02:10 +02:00
Martin Vogel f7cfccfd0c Merge pull request #2160 from htarnacki/fix/cli-json-array-args
test(cli): pin JSON array literal handling for array-typed arguments (#2150)
2026-09-27 16:02:05 +02:00
Martin Vogel 4f7fa84e32 Merge pull request #2359 from TheDarkniteFalls/codex/gh023-branch-head-regression
test(pipeline): cover changed-file and empty-commit Branch HEAD refresh
2026-09-27 16:01:59 +02:00
Martin Vogel 11b662f9f7 Merge pull request #1716 from astandrik/codex/fix-1648-sanitized-build-config
test: verify sanitizer build configuration
2026-09-27 11:02:35 +02:00
Martin Vogel 4b0b5f258d Merge pull request #2158 from htarnacki/fix/jaxrs-relative-path
fix(routes): accept relative JAX-RS @Path templates and compose Scala class-level @Path (#2147)
2026-09-27 11:02:30 +02:00
Martin Vogel 77ab4bea87 fix(extract): definitions walk stack grows without a ceiling
walk_defs keeps its pending frames in a growable stack that was bounded by
an 8M-frame ceiling (env CBM_WALK_DEFS_MAX). At the ceiling wd_push logged
"extract.walk_defs_capped" once and then stopped pushing. Children are
pushed last-to-first, so a file wider than the ceiling lost its FIRST
definitions: a work cap decided graph content.

Fix: no ceiling. The stack doubles on demand, heap frames now come from the
memory core (cbm_realloc/cbm_free, class EXTRACT) instead of safe_realloc and
raw free, and the doubling is overflow-guarded (int capacity and size_t
byte count). The only thing that can stop the walk is an allocation failure,
and that is loud: logged at error level as "extract.walk_stack_alloc_failed"
(walker=walk_defs, pending, path) -- the same event the complexity walkers
use -- and the file's result is marked has_error with
"definitions walk: stack allocation failed", which the definitions passes
already report as a per-file extract error. The arena-backed path
(ctx->scratch) gets the same failure handling. Traversal order is unchanged.

CBM_WALK_DEFS_MAX is removed. It was read only in wd_stack_max(); it was not
documented anywhere (docs, --help, config, tests), so nothing else changes.

extract_defs.c loses its raw free() call, so the memory-core baseline for
the file drops from 5 to 4.

Test (extraction suite): walk_defs_wide_file_extracts_every_definition
extracts a C file with 1000 top-level functions with CBM_WALK_DEFS_MAX=256
set, and asserts every wd0..wd999 definition is present. RED on main
(extract.walk_defs_capped limit=256; wd0 missing), GREEN with the fix, RED
again with the production change reverted. The extraction (379), complexity
(5), ast_profile (10) and semantic (35) suites pass.

Real input: Linux kernel, index-only, fresh cache and runtime dirs, same
machine. main and fix both produce 8,530,336 nodes and 15,764,128 edges,
SEMANTICALLY_RELATED 607 each, and the full node set (label, QN, lines) and
edge set (type, source QN, target QN) hash identically -- no kernel file
approaches the old ceiling. Index wall time 210.0 s (main) vs 194.4 s (fix),
within run-to-run noise.

Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-09-26 20:59:00 +02:00
News ed991154f2 fix(windows): preserve mkstemp errors through cleanup
Signed-off-by: News <knewstimek@users.noreply.github.com>
2026-09-26 20:30:02 +09:00
Hubert Tarnacki bc960d87d6 test(cli): pin JSON array literal handling for array-typed arguments
`codebase-memory-mcp cli <tool> --flag value` builds the tool's JSON
arguments from typed flags. Array-typed parameters such as
`semantic_query` used to accept only repeated flags; the JSON spelling
shown in the MCP schema (`--semantic-query '["a","b"]'`) was stored as a
single opaque string element (#2150). `cli_add_typed` now expands such a
literal; this pins the edge cases of that contract so it cannot regress:

- a well-formed array of strings contributes its elements
- an explicit empty array `[]` contributes nothing (not the keyword "[]")
- a malformed literal stays one literal string, without an error
- non-string items are copied as typed values, not stringified
- literals and repeated flags mix, accumulating in argument order
- repeated literals accumulate

Signed-off-by: Hubert Tarnacki <hubert.tarnacki@gmail.com>
2026-09-26 09:26:00 +02:00
Mike Parsons efb231285d test(pipeline): cover changed-file and empty-commit branch HEAD refresh
Signed-off-by: Mike Parsons <212198286+TheDarkniteFalls@users.noreply.github.com>
2026-09-26 13:55:16 +12:00
Martin Vogel 5a9c72d8f8 test(watcher): pin the pending-free drain on a held state, not a git probe
watcher_unwatch_drains_pending_free failed three times on macos-14 CI
with `index_call_count == 0, expected 1` at its dirty-poll precondition.
That precondition needs every git subprocess of one poll (rev-parse
HEAD, status, submodule foreach) to succeed. A transient probe failure
(spawn refused under runner load, a non-zero exit) makes that poll a
fail-closed no-op by design: #937 leaves the baseline uncommitted and
the next poll retries. Several of those paths return without a log
line, which matches the CI output exactly: watch, baseline, FAIL, with
no watcher.changed and no watcher.git.failed. Holding a spawn failure
with cbm_subprocess_force_spawn_eagain_for_testing reproduces that
output deterministically. This is a test race, not a production defect.

The precondition was also unrelated to the contract under test. A poll
that stopped draining would neither crash nor leak, because
cbm_watcher_free frees the same deferred list. So the old test could not
see a broken drain at all.

Add a test-only seam, cbm_watcher_test_pending_free_count, and assert
the stable states the watcher holds: 0 parked before unwatch, 1 after,
0 after the next poll with no index work, and still 0 after a further
poll. No assertion depends on a git probe succeeding. Dirty-poll
reindexing stays covered by watcher_detects_dirty_worktree and
watcher_modify_tracked_file.

Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-09-26 00:27:53 +02:00
Ivan Lin ff8dd47011 fix(scoop): address v0.11.0 review feedback
Signed-off-by: Ivan Lin <35771002+ivanlinhf@users.noreply.github.com>
2026-09-26 06:23:52 +08:00
Martin Vogel 3e67838b05 Merge branch 'main' into fix/windows-unicode-repo-paths
Resolve the RUN_TEST list conflict in tests/test_daemon_application.c by keeping both sides' new tests.

Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-09-25 23:15:24 +02:00
Martin Vogel 64c23fab6c Merge pull request #2282 from knewstimek/pr/windows-worker-recovery-fix
fix(windows): preserve worker recovery errors
2026-09-25 19:12:42 +02:00
Martin Vogel ff127ea44c Merge branch 'main' into codex/fix-1648-sanitized-build-config 2026-09-25 19:07:24 +02:00
Martin Vogel d772b1e5af Merge branch 'main' into fix/jaxrs-relative-path 2026-09-25 19:07:21 +02:00
Martin Vogel da3ea36339 Merge pull request #1832 from cdeust/feat/doclinks-markdown
feat(pipeline): link markdown file references into the graph
2026-09-25 19:06:55 +02:00
Martin Vogel 8ab13c94f6 Merge pull request #2263 from tamerbak/fix/smoke-tool-inventory
Fix/smoke tool inventory
2026-09-25 19:06:37 +02:00
Martin Vogel c98323bff7 Merge pull request #2199 from astandrik/fix/1696-smoke-runtime-isolation
fix(test): isolate smoke harness daemon runtime
2026-09-25 19:06:31 +02:00
Martin Vogel a5550e1a9e Merge pull request #1768 from bmcnaboe/fix/hook-augment-worktree-tests
test(hook-augment): pin worktree payload-cwd resolution
2026-09-25 19:05:56 +02:00
Martin Vogel 5c69c149f9 Merge pull request #2272 from DeusData/fix/test-daemon-bootstrap-sync-spawn
fix(test): the ENOSPC bootstrap test no longer lets a deadline decide its verdict
2026-09-25 19:05:06 +02:00
Ivan Lin 64297ff3e8 chore(scoop): bump packaged manifest to 0.11.0
Sync pkg/scoop/codebase-memory-mcp.json with the Scoop Main bucket
manifest (v0.11.0): add arm64, notes, and matching hashes/URLs.

Signed-off-by: Ivan Lin <35771002+ivanlinhf@users.noreply.github.com>
2026-09-24 21:14:29 +08:00
Martin Vogel 92cafd1ec8 Merge branch 'main' into fix/hook-augment-worktree-tests 2026-09-24 07:39:35 +02:00
Martin Vogel fcdc6bedb7 Merge branch 'main' into fix/smoke-tool-inventory 2026-09-24 07:39:20 +02:00
Martin Vogel f07c18702a Merge branch 'main' into fix/1696-smoke-runtime-isolation 2026-09-24 07:39:17 +02:00
Martin Vogel a6d3d5d820 Merge branch 'main' into codex/fix-1648-sanitized-build-config 2026-09-24 07:39:13 +02:00
Martin Vogel cf7eecd7d0 Merge branch 'main' into fix/jaxrs-relative-path 2026-09-24 06:57:47 +02:00
Martin Vogel 9b5bf70dc4 Merge branch 'main' into fix/test-daemon-bootstrap-sync-spawn 2026-09-24 04:51:00 +02:00
Martin Vogel 5958f546dc Merge pull request #2273 from DeusData/distill/1245-service-pattern-boundaries
fix(service-patterns): match library ids on identifier boundaries
2026-09-24 04:35:34 +02:00
Martin Vogel 5c0b241877 Merge pull request #2275 from DeusData/fix/win-endpoint-dir-create-race
fix(daemon): losing the runtime-directory creation race is not a failure on Windows
2026-09-24 04:35:31 +02:00
Martin Vogel 1160fa3591 Merge pull request #2274 from DeusData/distill/1245-c-pointer-return-types
fix(extract): a C-family function's return type keeps its pointer and qualifiers
2026-09-24 01:21:43 +02:00
Martin Vogel b0691e0d2f Merge pull request #1742 from bmcnaboe/codex/fix-daemon-runtime-sanitizer-timeout-only
fix(tests): scale daemon runtime sanitizer timeout
2026-09-24 01:21:38 +02:00
Martin Vogel 181c03dc18 Merge pull request #1741 from bmcnaboe/codex/fix-precommit-git-environment
fix(hooks): clear repository git environment for tests
2026-09-24 01:21:32 +02:00
Martin Vogel 95c91b8d8d Merge pull request #2140 from Lowpower/cursor/cli-help-format-json-cb65
feat(cli): point top-level cli --help at --format json
2026-09-23 23:53:21 +02:00
Hubert Tarnacki 246e4190c3 fix(routes): keep @Path("") unset instead of yielding an empty route path
Accepting relative JAX-RS templates made route_path_from_string_node return
"" for @Path(""), which is non-NULL and so replaced the "/" fallback with an
empty method path. @Path("") is legal JAX-RS and means "the class path
itself"; on main the empty value was rejected and the method fell back to
"/" like a method without @Path. Return NULL for the empty case so that
behaviour is unchanged.

The regression covers both shapes: with a class-level @Path the method
composes to the class path, and without one the route stays "/" (with the
empty string it was dropped entirely, because join_route_paths returns the
NULL prefix for an empty path).

Signed-off-by: Hubert Tarnacki <hubert.tarnacki@gmail.com>
2026-09-23 11:18:16 +02:00
News 1d2bbc4259 fix(windows): preserve worker recovery errors
Signed-off-by: News <knewstimek@users.noreply.github.com>
2026-09-22 22:34:11 +09:00
Clément DeustandClaude Sonnet 5 9a9534cbc4 docs: list REFERENCES_FILE in the README edge types table
The full Edge Types list near the graph schema section still missed
the new REFERENCES_FILE type added by the doclinks pass. The
"selected" list earlier in the file is explicitly a subset and is
left as is.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Signed-off-by: Clément Deust <clement.deust@gmail.com>
2026-09-22 08:54:40 +02:00
Clément DeustandClaude Sonnet 5 6ae6cd4c3f fix(pipeline): address doclinks review feedback
Replace raw malloc/free with cbm_alloc/cbm_free (CBM_MEM_CLASS_EXTRACT)
and a growable CBM_DYN_ARRAY for matches. Remove the 4KiB line-copy
cap; lines are split in place instead of copied. Remove the
DOCLINK_MAX_REFS(256) cap; the ref vector now grows, is sorted by
target id, then collapsed. Track reference kind (bare, relative,
rooted) so /x never attempts a directory join and ./x never falls
back to root. Report per-file skips via cbm_pipeline_add_file_error
and cbm_log_warn, and check cbm_pipeline_check_cancel in the per-file
loop.

Add negative-control tests for all of the above, plus CRLF handling,
fenced-code-block pinning, bare URLs, backtick-basename exactness,
and ".." escaping.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Signed-off-by: Clément Deust <clement.deust@gmail.com>
2026-09-22 08:48:33 +02:00
Clément DeustandClaude Fable 5 f3bdf11a03 feat(pipeline): link markdown file references into the graph
Markdown docs reference other repo files constantly (a coding-standards
doc links the modules it governs, a README points at entry points) but
none of that surfaced as edges, so fan-in queries were blind to
documentation hubs. In an A/B retrieval benchmark I ran in August on a
docs-heavy repo, the graph's top fan-in answer was off by roughly 17x:
the most-referenced file was a standards doc with 173 references and
zero inbound edges.

New pre-dump pass, pass_doclinks.c, modeled on pass_configlink.c: three
strategies emit REFERENCES_FILE edges between existing File nodes only
(unresolvable targets are dropped, the pass never invents nodes):
inline links, backtick paths, bare path mentions. Targets resolve
against the referencing file's directory and the repo root; repeated
references collapse into one edge carrying strategy, confidence and
count. Registered in the pre-dump sequence after configlink and in the
incremental post-passes; REFERENCES_FILE added to the skill's edge-type
list and the structural/language contract tests.

Tests mirror test_configlink.c (real files in a tmpdir, File nodes in a
gbuf, run the pass, assert edges): inline link, backtick, bare mention,
http/anchor ignored, anchor-suffixed file link, dedupe with count,
relative-vs-root resolution, unresolvable-target guard, NULL repo_path
skip.

A companion change adds the same linking for shell files (source lines
and script invocations); split out to keep each change reviewable.

Validation: scripts/build.sh clean; focused serial runner (doclinks,
configlink, pipeline, edge_structural, lang_contract) 340 passed under
ASan/UBSan; cppcheck clean on the new files with the repo's flags.

Signed-off-by: Clément Deust <clement.deust@gmail.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-22 08:06:50 +02:00
Martin Vogel e783f73d75 Merge pull request #2269 from DeusData/fix/ci-changes-large-diff-fallback
ci(pr): the changes job survives an un-renderable diff and no longer fails open on large file lists
2026-09-22 03:04:08 +02:00
Martin Vogel 8b57fe2a2b Merge pull request #2225 from tonydzi/docs/tool-count-17
docs: MCP tool count is 17; document get_file_outline, compare_graphs, check_index_coverage
2026-09-22 02:18:40 +02:00
Martin Vogel d1b2548ee8 Merge pull request #2270 from DeusData/docs/contributing-ai-contributions
docs(contributing): terms for AI-assisted and AI-authored contributions; who speaks for the project
2026-09-22 02:17:58 +02:00
Martin Vogel 9b7d63f579 Merge pull request #1931 from ilyabrykau-orca/fix/go-cgo-pseudo-import
fix(extract): drop cgo's `import "C"` pseudo-package
2026-09-22 02:00:11 +02:00
Lowpower 2f557f5398 style(cli): clang-format CBM_CLI_USAGE and help-text test
Signed-off-by: Lowpower <3133734+Lowpower@users.noreply.github.com>
2026-09-21 23:47:50 +00:00
Lowpower aaa72fbe60 feat(cli): point top-level cli --help at --format json
CLI_USAGE described outer --json but did not mention tool-level
--format json. Add a help-only pointer that tools which accept format
support --format tree|json, and distinguish payload JSON from the full
MCP envelope. No new flags, env vars, or output-default changes.

Fixes #2102

Signed-off-by: Lowpower <3133734+Lowpower@users.noreply.github.com>
2026-09-21 23:47:50 +00:00