Skip to content

Commit 9f2d3e5

Browse files
authored
Merge branch 'main' into agent/fix-worker-error-transport
2 parents 8fc04c0 + d6be58e commit 9f2d3e5

46 files changed

Lines changed: 3982 additions & 276 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.github/pr-acknowledgement.md‎

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<!--
2+
Posted automatically on every newly opened pull request by
3+
.github/workflows/pr-acknowledgement.yml
4+
5+
EDIT THIS FILE to change what contributors are told. Blank it out to stop
6+
posting acknowledgements entirely — no workflow change needed.
7+
8+
Keep it short, and keep it honest about what happens next. A promise of a
9+
timeline you will not meet is worse than no acknowledgement at all.
10+
Remove the review-status section below the moment it stops being true.
11+
-->
12+
13+
Thanks for opening this — it has been seen, and it is queued.
14+
15+
This note is automated, but it is not a brush-off: it exists so you know where your PR stands instead of having to guess from silence.
16+
17+
**Current review status: working through a backlog.** `0.9.1-rc.1` is out, so the release freeze that held reviews is over — but it left a large queue of open pull requests behind it, and we are reading through them oldest-first. The background is in [discussion #1144](https://github.com/DeusData/codebase-memory-mcp/discussions/1144).
18+
19+
What that means for this PR, concretely:
20+
21+
- **It will not be closed for inactivity.** No stale bot touches pull requests here.
22+
- It may still sit a while before a human reads it. That is on us, not on you.
23+
- Older PRs are read first, so a recent one is not being skipped — it is behind a queue.
24+
25+
Things that will genuinely speed it up whenever review does happen:
26+
27+
- **Keep it rebased** on `main` — the tree is moving quickly right now, and a conflicting branch cannot be reviewed as the diff you intended.
28+
- **Get CI green**, or say which failures you believe are pre-existing.
29+
- **Keep the change to one claim.** Bundled features and refactors get split before they get merged, which costs you a round trip.
30+
- Every commit needs a sign-off (`git commit -s`) — CI enforces DCO.
31+
32+
If this fixes a bug, a reproduction we can run is worth more than a description of the symptom.
33+
34+
Thanks for contributing, and sorry in advance for the wait.

‎.github/workflows/_build.yml‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ jobs:
5959
if: startsWith(matrix.os, 'ubuntu')
6060
run: sudo apt-get update && sudo apt-get install -y zlib1g-dev
6161

62-
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
62+
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
6363
with:
6464
node-version: "22"
6565

@@ -140,7 +140,7 @@ jobs:
140140
make
141141
zip
142142
143-
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
143+
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
144144
with:
145145
node-version: "22"
146146

@@ -213,7 +213,7 @@ jobs:
213213
make
214214
zip
215215
216-
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
216+
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
217217
with:
218218
node-version: "22"
219219

@@ -283,7 +283,7 @@ jobs:
283283
- name: Install deps
284284
run: sudo apt-get update && sudo apt-get install -y zlib1g-dev
285285

286-
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
286+
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
287287
with:
288288
node-version: "22"
289289

‎.github/workflows/_test.yml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -403,7 +403,7 @@ jobs:
403403
make
404404
git
405405
406-
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
406+
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
407407
with:
408408
node-version: "22"
409409

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
name: PR acknowledgement
2+
3+
# Posts one acknowledgement comment when a pull request is opened, so a
4+
# contributor learns the current review status immediately instead of inferring
5+
# it from silence.
6+
#
7+
# The message text lives in `.github/pr-acknowledgement.md`. Edit that file to
8+
# change what is said; blank it (or delete it) to turn acknowledgements off
9+
# without touching this workflow. No code change is needed to switch it.
10+
#
11+
# SECURITY — this uses `pull_request_target`, which runs against the BASE repo
12+
# with a token that can write. That is required: a `pull_request` trigger gives
13+
# fork PRs a read-only token, so commenting on exactly the contributions we most
14+
# want to acknowledge would fail.
15+
#
16+
# The safety rule that makes it sound: this job NEVER checks out, builds, or
17+
# executes pull-request code. `actions/checkout` here resolves to the base
18+
# commit (the default under `pull_request_target`), and it is used only to read
19+
# the message file out of our own tree. Do not add a `ref:` pointing at the PR
20+
# head, and do not add a build step. Nothing from the PR is interpolated into a
21+
# shell command either — the body comes from a file, and the PR number is passed
22+
# through the environment rather than expanded inline.
23+
24+
on:
25+
pull_request_target:
26+
types: [opened]
27+
28+
permissions:
29+
contents: read
30+
31+
jobs:
32+
acknowledge:
33+
runs-on: ubuntu-latest
34+
# Bots do not read comments, and acknowledging our own PRs is noise.
35+
if: >-
36+
github.event.pull_request.user.type != 'Bot' &&
37+
github.event.pull_request.author_association != 'OWNER'
38+
permissions:
39+
pull-requests: write
40+
steps:
41+
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
42+
with:
43+
# Base commit only — never the PR head. See the security note above.
44+
persist-credentials: false
45+
46+
- name: Post acknowledgement
47+
env:
48+
GH_TOKEN: ${{ github.token }}
49+
PR_NUMBER: ${{ github.event.pull_request.number }}
50+
REPO: ${{ github.repository }}
51+
run: |
52+
set -euo pipefail
53+
MESSAGE_FILE=.github/pr-acknowledgement.md
54+
55+
if [ ! -f "$MESSAGE_FILE" ]; then
56+
echo "No $MESSAGE_FILE in the base tree — acknowledgements are off."
57+
exit 0
58+
fi
59+
60+
# An empty or whitespace-only file is the documented off switch.
61+
if [ -z "$(tr -d '[:space:]' < "$MESSAGE_FILE")" ]; then
62+
echo "$MESSAGE_FILE is blank — acknowledgements are off."
63+
exit 0
64+
fi
65+
66+
gh pr comment "$PR_NUMBER" --repo "$REPO" --body-file "$MESSAGE_FILE"
67+
echo "Acknowledged PR #${PR_NUMBER}."

‎.github/workflows/release.yml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,7 @@ jobs:
304304
305305
# ── npm ──────────────────────────────────────────────────
306306
- name: Setup Node
307-
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
307+
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
308308
with:
309309
node-version: '22'
310310
registry-url: 'https://registry.npmjs.org'

‎.github/workflows/scorecard.yml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,6 @@ jobs:
2727
publish_results: true
2828

2929
- name: Upload SARIF results
30-
uses: github/codeql-action/upload-sarif@54f647b7e1bb85c95cddabcd46b0c578ec92bc1a # v4
30+
uses: github/codeql-action/upload-sarif@7188fc363630916deb702c7fdcf4e481b751f97a # v4
3131
with:
3232
sarif_file: results.sarif

‎.github/workflows/stale.yml‎

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,24 @@
11
name: Stale awaiting-reporter
22

3+
# Marks inactive `awaiting-reporter` issues as `stale`. It NEVER closes them:
4+
# closing an issue as "not planned" is a maintainer judgement, not an automated
5+
# one, so this workflow only surfaces a review queue and a human decides.
6+
#
37
# Only touches issues that a maintainer has explicitly marked `awaiting-reporter`.
48
# Never touches pull requests, and never touches issues without that label.
59
# A reporter comment removes `stale` and resets the clock.
10+
#
11+
# WHY never close (2026-07-26): `awaiting-reporter` is applied by hand and means
12+
# "the reporter owes the next step". It was also being used to mean "we will come
13+
# back to this", which is a different thing. In that second case the automation was
14+
# closing issues the project itself owed work on — #56 was a confirmed bug with an
15+
# in-tree reproduction (tests/repro/repro_issue56.c, landed via #667) queued to close
16+
# as `not_planned` purely because a maintainer had the last word. A mislabel should
17+
# cost a stale tag, never a silently discarded bug.
18+
#
19+
# The `stale` label is therefore a review queue, not a countdown. Sweep it during
20+
# triage: clear the label where we owe the next step, and close by hand where the
21+
# thread is genuinely dead.
622

723
on:
824
schedule:
@@ -18,27 +34,28 @@ jobs:
1834
permissions:
1935
issues: write
2036
steps:
21-
- uses: actions/stale@eb5cf3af3ac0a1aa4c9c45633dd1ae542a27a899 # v10.3.0
37+
- uses: actions/stale@1e223db275d687790206a7acac4d1a11bd6fe629 # v10.4.0
2238
with:
2339
only-labels: 'awaiting-reporter'
2440
stale-issue-label: 'stale'
2541
days-before-issue-stale: 21
26-
days-before-issue-close: 14
42+
# -1 disables automated closing entirely. Marking stale is the whole job.
43+
days-before-issue-close: -1
2744
# Never act on pull requests with this workflow.
2845
days-before-pr-stale: -1
2946
days-before-pr-close: -1
47+
# Belt-and-braces: these categories must never be auto-flagged even if
48+
# `awaiting-reporter` is applied to them by mistake. `task` covers the
49+
# umbrella/epic issues (incl. the pinned roadmap index #595), and
50+
# `maintainer-notes` is the explicit "we owe the next step" escape hatch.
51+
exempt-issue-labels: 'security,task,maintainer-notes'
3052
remove-stale-when-updated: true
31-
close-issue-reason: not_planned
3253
operations-per-run: 60
3354
ascending: true
3455
stale-issue-message: >
3556
This issue has been waiting on more information for 21 days (a
3657
version, exact steps, or a public repro), so it's now marked
37-
`stale`. It will be closed in 14 days if there's no update — just
38-
add a comment to keep it open. We're happy to pick it back up the
39-
moment we can reproduce it.
40-
close-issue-message: >
41-
Closing because we haven't received the requested details and can't
42-
reproduce it as-is. This isn't a "won't fix" — please comment with
43-
the info (version + a public repro) and we'll reopen and dig in.
44-
Thanks for the report.
58+
`stale`. **It will not be closed automatically** — a maintainer
59+
reviews stale issues by hand. Adding a comment with the details
60+
clears the label and puts it straight back in the queue. We're happy
61+
to pick it back up the moment we can reproduce it.

‎CONTRIBUTING.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ The binary is output to `build/c/codebase-memory-mcp`.
2626
scripts/test.sh
2727
```
2828

29-
This builds with ASan + UBSan and runs all tests (~2040 cases). Key test files:
29+
This builds with ASan + UBSan and runs the full C test suite. Key test files:
3030
- `tests/test_pipeline.c` — pipeline integration tests
3131
- `tests/test_httplink.c` — HTTP route extraction and linking
3232
- `tests/test_mcp.c` — MCP protocol and tool handler tests
@@ -63,7 +63,7 @@ src/
6363
watcher/ Git-based background auto-sync
6464
cli/ CLI subcommands (install, update, uninstall, config)
6565
ui/ Graph visualization HTTP server (first-party httpd)
66-
internal/cbm/ Tree-sitter AST extraction (64 languages, vendored C grammars)
66+
internal/cbm/ Language registry, AST extraction, and vendored grammars
6767
vendored/ sqlite3, yyjson, mimalloc, xxhash, tre, nomic
6868
graph-ui/ React/Three.js frontend for graph visualization
6969
scripts/ Build, test, lint, security audit scripts

‎Makefile.cbm‎

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -417,6 +417,19 @@ PROD_SRCS = $(FOUNDATION_SRCS) $(STORE_SRCS) $(CYPHER_SRCS) $(MCP_SRCS) $(DAEMON
417417
EXISTING_C_SRCS = $(EXTRACTION_SRCS) $(LSP_SRCS) $(TS_RUNTIME_SRC) \
418418
$(GRAMMAR_SRCS) $(AC_LZ4_SRCS) $(ZSTD_SRCS) $(SQLITE_WRITER_SRC)
419419

420+
# Project headers, as prerequisites for the targets built in one compiler
421+
# invocation from sources (test-runner, test-repro-runner, test-runner-tsan,
422+
# codebase-memory-mcp, test-foundation). Those rules list only .c files, so
423+
# editing a header changed nothing make could see and the target was NOT
424+
# rebuilt — an incremental build then silently tested the OLD header value.
425+
# Found while revert-checking a constants.h change: the check passed because
426+
# nothing had recompiled.
427+
#
428+
# Vendored trees are deliberately excluded — they are pinned, they carry their
429+
# own explicit dep lists (LSP_UNITY_DEPS, TS_RUNTIME_DEPS), and globbing tens of
430+
# thousands of grammar headers would cost more than it protects.
431+
PROJECT_HDRS = $(wildcard src/*.h src/*/*.h $(CBM_DIR)/*.h tests/*.h tests/repro/*.h)
432+
420433
# ── Test sources ─────────────────────────────────────────────────
421434

422435
TEST_FOUNDATION_SRCS = \
@@ -645,7 +658,7 @@ $(BUILD_DIR):
645658

646659
# ── Foundation-only test (fast, no extraction) ───────────────────
647660

648-
$(BUILD_DIR)/test-foundation: $(TEST_FOUNDATION_SRCS) $(FOUNDATION_SRCS) | $(BUILD_DIR)
661+
$(BUILD_DIR)/test-foundation: $(TEST_FOUNDATION_SRCS) $(FOUNDATION_SRCS) $(PROJECT_HDRS) | $(BUILD_DIR)
649662
$(CC) $(CFLAGS_TEST) -o $@ $(TEST_FOUNDATION_SRCS) $(FOUNDATION_SRCS) $(LDFLAGS_TEST)
650663

651664
test-foundation: $(BUILD_DIR)/test-foundation
@@ -761,7 +774,7 @@ $(UNIXCODER_OBJ): $(UNIXCODER_BLOB_SRC) vendored/nomic/code_vectors.bin | $(BUIL
761774
OBJS_VENDORED_TEST = $(MIMALLOC_OBJ_TEST) $(SQLITE3_OBJ_TEST) $(TRE_OBJ_TEST) $(GRAMMAR_OBJS_TEST) $(TS_RUNTIME_OBJ_TEST) $(LSP_OBJ_TEST) $(PP_OBJ_TEST) $(LZ4_OBJ_TEST) $(ZSTD_OBJ_TEST) $(UNIXCODER_OBJ)
762775
OBJS_VENDORED_TSAN = $(MIMALLOC_OBJ_TSAN) $(SQLITE3_OBJ_TSAN) $(TRE_OBJ_TSAN) $(GRAMMAR_OBJS_TSAN) $(TS_RUNTIME_OBJ_TSAN) $(LSP_OBJ_TSAN) $(PP_OBJ_TSAN) $(LZ4_OBJ_TSAN) $(ZSTD_OBJ_TSAN) $(UNIXCODER_OBJ)
763776

764-
$(BUILD_DIR)/test-runner: $(ALL_TEST_SRCS) $(PROD_SRCS) $(EXTRACTION_SRCS) $(AC_LZ4_SRCS) $(ZSTD_SRCS) $(SQLITE_WRITER_SRC) $(OBJS_VENDORED_TEST) | $(BUILD_DIR)
777+
$(BUILD_DIR)/test-runner: $(ALL_TEST_SRCS) $(PROD_SRCS) $(EXTRACTION_SRCS) $(AC_LZ4_SRCS) $(ZSTD_SRCS) $(SQLITE_WRITER_SRC) $(OBJS_VENDORED_TEST) $(PROJECT_HDRS) | $(BUILD_DIR)
765778
$(CC) $(CFLAGS_TEST) -Itests -Itests/repro -o $@ \
766779
$(ALL_TEST_SRCS) $(PROD_SRCS) \
767780
$(EXTRACTION_SRCS) $(AC_LZ4_SRCS) $(ZSTD_SRCS) $(SQLITE_WRITER_SRC) \
@@ -789,7 +802,7 @@ test-focused: $(BUILD_DIR)/test-runner
789802
# Mirrors test-runner's link line but uses repro_main.c (own main + counters)
790803
# and TEST_REPRO_SRCS instead of ALL_TEST_SRCS. Exits non-zero while any bug is
791804
# still reproduced (the expected state); bug-repro.yml surfaces it as a board.
792-
$(BUILD_DIR)/test-repro-runner: $(TEST_REPRO_SRCS) $(PROD_SRCS) $(EXTRACTION_SRCS) $(AC_LZ4_SRCS) $(ZSTD_SRCS) $(SQLITE_WRITER_SRC) $(OBJS_VENDORED_TEST) | $(BUILD_DIR)
805+
$(BUILD_DIR)/test-repro-runner: $(TEST_REPRO_SRCS) $(PROD_SRCS) $(EXTRACTION_SRCS) $(AC_LZ4_SRCS) $(ZSTD_SRCS) $(SQLITE_WRITER_SRC) $(OBJS_VENDORED_TEST) $(PROJECT_HDRS) | $(BUILD_DIR)
793806
$(CC) $(CFLAGS_TEST) -Itests -o $@ \
794807
$(TEST_REPRO_SRCS) $(PROD_SRCS) \
795808
$(EXTRACTION_SRCS) $(AC_LZ4_SRCS) $(ZSTD_SRCS) $(SQLITE_WRITER_SRC) \
@@ -831,7 +844,7 @@ TSAN_OPTIONS ?= halt_on_error=1
831844
# Normal ASan/native/soak paths remain uncapped. High-worker TSan diagnostics
832845
# invoke test-runner-tsan directly so release gates cannot drift accidentally.
833846

834-
$(BUILD_DIR)/test-runner-tsan: $(ALL_TEST_SRCS) $(PROD_SRCS) $(EXTRACTION_SRCS) $(AC_LZ4_SRCS) $(ZSTD_SRCS) $(SQLITE_WRITER_SRC) $(OBJS_VENDORED_TSAN) | $(BUILD_DIR)
847+
$(BUILD_DIR)/test-runner-tsan: $(ALL_TEST_SRCS) $(PROD_SRCS) $(EXTRACTION_SRCS) $(AC_LZ4_SRCS) $(ZSTD_SRCS) $(SQLITE_WRITER_SRC) $(OBJS_VENDORED_TSAN) $(PROJECT_HDRS) | $(BUILD_DIR)
835848
$(CC) $(CFLAGS_TSAN) -Itests -Itests/repro -o $@ \
836849
$(ALL_TEST_SRCS) $(PROD_SRCS) \
837850
$(EXTRACTION_SRCS) $(AC_LZ4_SRCS) $(ZSTD_SRCS) $(SQLITE_WRITER_SRC) \
@@ -904,7 +917,7 @@ $(BUILD_DIR)/.build-config: build-config-check | $(BUILD_DIR)
904917
else mv -f $@.tmp $@; rm -f $(BUILD_DIR)/codebase-memory-mcp; \
905918
echo "=== build config changed -> full rebuild: $(BUILD_CONFIG_SIG) ==="; fi
906919

907-
$(BUILD_DIR)/codebase-memory-mcp: $(MAIN_SRC) $(PROD_SRCS) $(EXTRACTION_SRCS) $(AC_LZ4_SRCS) $(ZSTD_SRCS) $(SQLITE_WRITER_SRC) $(OBJS_VENDORED_PROD) $(BUILD_DIR)/.build-config | $(BUILD_DIR)
920+
$(BUILD_DIR)/codebase-memory-mcp: $(MAIN_SRC) $(PROD_SRCS) $(EXTRACTION_SRCS) $(AC_LZ4_SRCS) $(ZSTD_SRCS) $(SQLITE_WRITER_SRC) $(OBJS_VENDORED_PROD) $(BUILD_DIR)/.build-config $(PROJECT_HDRS) | $(BUILD_DIR)
908921
$(CC) $(CFLAGS_PROD) -o $@ \
909922
$(MAIN_SRC) $(PROD_SRCS) \
910923
$(EXTRACTION_SRCS) $(AC_LZ4_SRCS) $(ZSTD_SRCS) $(SQLITE_WRITER_SRC) \

‎README.md‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -616,9 +616,11 @@ JSON arguments can also be piped on stdin. Inline JSON remains accepted for back
616616
| `get_code_snippet` | Read source code for a function by qualified name. |
617617
| `get_architecture` | Codebase overview: languages, packages, routes, hotspots, clusters, ADR. |
618618
| `search_code` | Grep-like text search within indexed project files. |
619-
| `manage_adr` | CRUD for Architecture Decision Records. |
619+
| `manage_adr` | CRUD for Architecture Decision Records. Query modes do not wait behind a same-project reindex; writes remain serialized. |
620620
| `ingest_traces` | Ingest runtime traces to validate HTTP_CALLS edges. |
621621

622+
`manage_adr` query modes (`get` and `sections`) use the server's cached query store so they can proceed while a same-project reindex is running. If another process publishes a replacement store during reindexing, they can return the pre-publication ADR until idle eviction refreshes that cache. Updates remain serialized through the project mutation guard.
623+
622624
## Graph Data Model
623625

624626
### Node Labels

0 commit comments

Comments
 (0)