Skip to content

Commit 894c392

Browse files
authored
Merge pull request #30 from ngallodev/sync/upstream-13b-review-20261102
sync: integrate upstream checkpoint 13B
2 parents c5e665d + 8dd478e commit 894c392

47 files changed

Lines changed: 6557 additions & 502 deletions

Some content is hidden

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

‎docs/UPSTREAM_308_CANDIDATE_AUDIT_20260912.md‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
The [campaign plan](upstream-sync/PLAN.md), [machine ledger](upstream-sync/ledger.json)
66
and [933-commit inventory](upstream-sync/commits.tsv) extend this canonical ledger.
7+
The 2026-11-02 continuation receipts are linked from the plan; current 13B
8+
integration and validation details are in [13b.md](upstream-sync/13b.md).
79
Fork baseline is `ff8b8906c6807953336609cc7f464e7e4ef3cf7b`; common ancestor
810
`8df0639c6268afe9888979e72b9797aa2cc1de7c`; pinned upstream target
911
`6c0ce230ee26ab8d263eb5235ebf73755558344e`. Live upstream inventory reached

‎docs/upstream-sync/13b.md‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# 13B integration receipt
2+
3+
- Integration merge: `408d24dfb657c280ec36e7e7cc913c1ef1612b6a` (parents `27b731cec45e2353303738ac6d8e77acbef42b7c` and `4c80d89edf1283cfeaa7e60ecbf40c9d2eb2b689`).
4+
- Upstream interval: `5dc83ac9fa363d51706a70977840b61ea59ce9db` (exclusive) to `4c80d89edf1283cfeaa7e60ecbf40c9d2eb2b689` (inclusive), 119 commits. Merge base is exact 13A checkpoint; merge retained both parents.
5+
- Shared source carried: Python namespace/import/C3 resolution and future annotations, PHP trait/global-use resolution, Go receiver identities/multi-return, ASP.NET routes, test-file scope correction, graph follow-up guidance, and extraction/pipeline changes. `CBM_INDEX_FORMAT_VERSION` remains 4; semantic coverage version is 9.
6+
- Conflicts: `src/cli/hook_augment.c` (merged neutral payload parser with follow-up guidance, adapted names to native `trace`/`snippet`/`search`); `src/pipeline/pipeline_internal.h` (retained both definition-property and route declarations). Upstream modifications to `src/mcp/mcp.c` and `tests/test_mcp.c` were removed to preserve CLI architecture. One MCP-backed follow-up test was folded into the adjacent native-operation-host hook test. No MCP server/transport was restored.
7+
- Validation: `scripts/build-dev.sh` passed. `scripts/test.sh --suites 'extraction parallel pipeline php_lsp registry edge_types_probe doc_mentions_go doc_links_pdf'` passed 1,502 tests under ASan/UBSan after updating a stale LSP surface fixture from codec v2 to v3; `scripts/test.sh --smart --tests 'pipeline:pipeline_lsp_surface_decode_preserves_array_order_and_nulls'` passed 1/1; `scripts/test.sh --smart --tests 'cli:cli_hook_augment_context_tracks_search_json_shape'` passed 1/1. The first broad run exposed the stale fixture and an early-return arena leak; corrected fixture passes and cleans up normally.
8+
- `python3 scripts/ci/check-github-actions-policy.py` passed (manual/reusable events only; Jenkins owns automatic CI). No Windows validation, push, PR, or Jenkins run is claimed for this checkpoint.
9+
- Review/acceptance and full Jenkins remain pending. Graph CLI fallback: `codebase-memory-cli projects --json` failed with `secure CLI coordination could not be created (cache-resolve)`; structural claims above use exact Git/source fallback. Parent owns the canonical backlog entry.
10+
11+
## 2026-11-02 draft and continuation
12+
13+
- Status: `verification-pending`; [draft PR #30](https://github.com/ngallodev/codebase-memory-cli/pull/30), base `main`, is not merged or independently reviewed.
14+
- Fork base `27b731cec45e2353303738ac6d8e77acbef42b7c`; upstream target `4c80d89edf1283cfeaa7e60ecbf40c9d2eb2b689`; exact merge and parents are above. At draft creation, fork/upstream ancestry counts were 371/900; the 13B candidate had 373/781. Recompute after further commits or fetches.
15+
- At candidate `45d0b6d37`, the Actions policy checker and its four focused tests passed. No Jenkins qualification or Windows verification is claimed for this candidate. Unauthenticated Jenkins API returned HTTP 403 and GitHub's combined status for the fork base had no contexts; PR discovery and result publication are unverified.
16+
- Priority fixes #2207 and #2315/#2864 are being investigated in separate branches `fix/upstream-2207-lifetime-20261102` and `fix/upstream-adr-race-20261102`. Their first Agent Runs and lineage-preserving retries became orphaned and were terminated without completion. The #2207 patch is committed at `96e44e2a87492e4e2ac66ad5c39b6a889192f995` in [draft PR #31](https://github.com/ngallodev/codebase-memory-cli/pull/31). Linux `daemon_ipc` passed 57 tests under ASan/UBSan after commit; Jenkins and concurrent-interleaving review remain pending. The ADR branch remains unchanged. Do not assume their code is accepted or tested.
17+
- Existing local `sync/upstream-remainder-20261102` contains provisional true merges through 13H (`84682e966b2df76d6eeb04655d5eabb7ee5833e7`) and an unresolved 13I merge with target `d1d8bbfa8fb52b0312dbbf1bf48b2787a7273a56`. Its Agent Run failed (`seal_failed`); preserve the unmerged worktree and inspect/resolve its conflicts only after reconciling its evidence. 13C–13H require independent review and qualification before advancing a dependent PR stack.
18+
- PRs #28 and #29 were closed after confirming their exact heads were ancestors of main; #27 was already merged. The main checkout's unrelated untracked files were preserved.
19+
- #2207 review: the two-file patch has the same stable patch ID as upstream merge `c80a2569995c44d7ad8522ea97e5944c4b5265be`. Its same-process fast paths avoid closing a second descriptor when a claim is already observed. A concurrent probe/acquire interleaving remains a review question: the registry check releases its mutex before the probe opens and closes the file, so a new claim could arise in between. Verify or eliminate that interleaving before treating the correction as complete. Do not infer test success from the interrupted worker builds.
20+
21+
The canonical upstream audit remains `docs/UPSTREAM_308_CANDIDATE_AUDIT_20260912.md` (the filename is retained for stable links). PR25 documentation cleanup must preserve that authority and its existing references, either at this path or through a deliberate compatibility link; this receipt does not replace the canonical audit.

‎docs/upstream-sync/PLAN.md‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
# Upstream synchronization campaign — 2026-11-01
22

3+
## Live continuation — 2026-11-02
4+
5+
13A is now on the authoritative fork main at `27b731cec45e2353303738ac6d8e77acbef42b7c`.
6+
The pinned continuation target is `a5b248f47272413189746589b9a2c551c6b6c5ec`;
7+
13B is integrated locally with validation recorded in [13b.md](13b.md), and
8+
13C–13L remain in sequence. Older campaign inventories and PR bases below are
9+
historical; the continuation run contract governs this stack.
10+
311
This campaign supplements the [canonical integration ledger](../UPSTREAM_308_CANDIDATE_AUDIT_20260912.md); it does not supersede older unresolved semantic dispositions. Machine status and per-checkpoint acceptance live in [ledger.json](ledger.json). [commits.tsv](commits.tsv) enumerates all 933 reachable campaign commits once, including 578 merges and 355 non-merges. Subsystem tags derive from changed paths; they are triage, not proof of implementation.
412

513
## Verified baseline

‎docs/upstream-sync/ledger.json‎

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -256,22 +256,33 @@
256256
"upstream_checkpoint": "4c80d89edf1283cfeaa7e60ecbf40c9d2eb2b689",
257257
"upstream_commits": 119,
258258
"ancestry_validated": true,
259-
"fork_base": null,
259+
"fork_base": "27b731cec45e2353303738ac6d8e77acbef42b7c",
260260
"depends_on": [
261261
"13A"
262262
],
263-
"state": "not_started",
264-
"branch": null,
265-
"merge_commit": null,
263+
"state": "integrated_local_review_pending",
264+
"branch": "sync/upstream-13b-20261102",
265+
"merge_commit": "408d24dfb657c280ec36e7e7cc913c1ef1612b6a",
266266
"draft_pr": null,
267-
"adaptations": [],
268-
"exclusions": [],
269-
"conflicts": [],
270-
"schema_migrations": "pending source verification",
271-
"policy_gate": "pending",
267+
"adaptations": [
268+
"Merged Python namespace/import and C3 resolution, PHP traits/global use, Go receiver identity and multi-return, ASP.NET route registration, and test-file scope correction.",
269+
"Adapted hook search follow-up guidance to native trace/snippet/search commands.",
270+
"Folded MCP-backed follow-up assertions into the native operation-host hook regression."
271+
],
272+
"exclusions": [
273+
"Removed upstream modifications to src/mcp/mcp.c and tests/test_mcp.c; no MCP server or transport restored."
274+
],
275+
"conflicts": [
276+
"src/cli/hook_augment.c: retained neutral operation payload parsing and added native CLI follow-up guidance.",
277+
"src/pipeline/pipeline_internal.h: retained both definition-property and route declarations.",
278+
"src/mcp/mcp.c and tests/test_mcp.c: modify/delete retained CLI-side deletion."
279+
],
280+
"schema_migrations": "No index format bump; CBM_INDEX_FORMAT_VERSION remains 4. Semantic coverage version is 9.",
281+
"policy_gate": "passed: python3 scripts/ci/check-github-actions-policy.py; manual/reusable only, Jenkins automatic CI.",
272282
"verification": {
273-
"local": "pending",
274-
"jenkins": "pending",
283+
"production_build": "passed: scripts/build-dev.sh",
284+
"focused": "passed: 1502 ASan/UBSan tests across extraction, parallel, pipeline, php_lsp, registry, edge_types_probe, doc_mentions_go, doc_links_pdf; targeted native hook and LSP surface regressions 1/1 each",
285+
"jenkins": "pending final pinned candidate",
275286
"windows": "not_run"
276287
},
277288
"acceptance": [
@@ -281,7 +292,7 @@
281292
"Focused changed-subsystem tests pass; record failures and native Windows limitations.",
282293
"Jenkins full exact-SHA qualification before recommending merge."
283294
],
284-
"next_action": "After previous reviewed integration, merge checkpoint; do not base on stale main.",
295+
"next_action": "Continue at 13C on this ancestry-preserving integration; review and acceptance remain pending.",
285296
"upstream_prs": [
286297
1041,
287298
1265,

‎internal/cbm/cbm.c‎

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,31 @@ void cbm_imports_push(CBMImportArray *arr, CBMArena *a, CBMImport imp) {
403403
arr->items[arr->count++] = imp;
404404
}
405405

406+
bool cbm_imports_local_span_binds_runtime_name(const CBMImportArray *imports, const char *name,
407+
size_t len) {
408+
if (!imports || !name) {
409+
return true;
410+
}
411+
bool seen = false;
412+
for (int i = 0; i < imports->count; i++) {
413+
const CBMImport *imp = &imports->items[i];
414+
if (!imp->local_name || strncmp(imp->local_name, name, len) != 0 ||
415+
imp->local_name[len] != '\0') {
416+
continue;
417+
}
418+
if (cbm_import_binds_runtime_name(imp)) {
419+
return true;
420+
}
421+
seen = true;
422+
}
423+
return !seen;
424+
}
425+
426+
bool cbm_imports_local_binds_runtime_name(const CBMImportArray *imports, const char *local_name) {
427+
return !local_name ||
428+
cbm_imports_local_span_binds_runtime_name(imports, local_name, strlen(local_name));
429+
}
430+
406431
void cbm_usages_push(CBMUsageArray *arr, CBMArena *a, CBMUsage usage) {
407432
GROW_ARRAY(arr, a);
408433
arr->items[arr->count++] = usage;

‎internal/cbm/cbm.h‎

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -398,11 +398,26 @@ typedef struct {
398398
const char *member; // ES named import: the exported name the local binds (`get` in
399399
// `import { get as navigate } from "axios"`); NULL otherwise
400400
bool is_default; // ES default import (`import X from "Y"`), JS/TS only (#1916)
401+
bool type_checking_only; // Python: inside a module-level `if TYPE_CHECKING:` block --
402+
// binds the name for annotations, never at runtime (#1277)
401403
CBMImportKind kind; // CBM_IMPORT_KIND_DEFAULT unless the syntax names a member kind
402404
} CBMImport;
403405

404-
/* Content-only ordered Python namespace facts; no resolved target identities. */
405-
#define CBM_PY_NAMESPACE_FACTS_VERSION 1u
406+
/* True when an import binds its local name at runtime. A Python import under
407+
* `if TYPE_CHECKING:` exists for annotations only: a call through that name
408+
* cannot happen, so no CALLS import map may bind it (an import_map edge
409+
* through it would be fabricated by construction). THE one rule every CALLS
410+
* import-map builder applies. */
411+
static inline bool cbm_import_binds_runtime_name(const CBMImport *imp) {
412+
return imp && !imp->type_checking_only;
413+
}
414+
415+
/* Content-only ordered Python namespace facts; no resolved target identities.
416+
* The version travels in the lsp_surface "py" payload, and a stored payload of
417+
* another version does not decode: an incremental run then re-extracts in full,
418+
* so stored facts of an older extraction never mix with fresh ones.
419+
* 2: string-literal statements are no effect; `from __future__` imports bind. */
420+
#define CBM_PY_NAMESPACE_FACTS_VERSION 2u
406421

407422
typedef enum {
408423
CBM_PY_NS_NOT_CAPTURED = 0,
@@ -1306,6 +1321,14 @@ void cbm_py_namespace_test_copy_fail_after(int successful_allocations);
13061321
void cbm_defs_push(CBMDefArray *arr, CBMArena *a, CBMDefinition def);
13071322
void cbm_calls_push(CBMCallArray *arr, CBMArena *a, CBMCall call);
13081323
void cbm_imports_push(CBMImportArray *arr, CBMArena *a, CBMImport imp);
1324+
/* True unless every import of `imports` that binds `local_name` is
1325+
* annotation-only (cbm_import_binds_runtime_name), so also true when no import
1326+
* names it: the rule for the builders that key IMPORTS edges by local name. */
1327+
bool cbm_imports_local_binds_runtime_name(const CBMImportArray *imports, const char *local_name);
1328+
/* The same for the `len` bytes at `name` (not NUL-terminated): lets a caller
1329+
* decide before it copies the name. */
1330+
bool cbm_imports_local_span_binds_runtime_name(const CBMImportArray *imports, const char *name,
1331+
size_t len);
13091332
void cbm_usages_push(CBMUsageArray *arr, CBMArena *a, CBMUsage usage);
13101333
void cbm_throws_push(CBMThrowArray *arr, CBMArena *a, CBMThrow thr);
13111334
void cbm_rw_push(CBMRWArray *arr, CBMArena *a, CBMReadWrite rw);

‎internal/cbm/doclink_go.c‎

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,10 @@
4343
* drops these lines and so carries no line number
4444
* at all.
4545
* G path go.mod: the module path
46-
* w says who keeps the node. A Go method node has a FLAT qualified name
47-
* (<dir>.<Method>), so a function, the methods of every receiver, a type and
48-
* a value of one name all claim the node <dir>.<name>, and within a file the
49-
* declaration on the LAST line keeps it (cbm_gbuf_upsert_node). w is 1 for
46+
* w says who keeps the node <dir>.<name>. A function, a type and a value of
47+
* one name all claim it, and within a file the declaration on the LAST line
48+
* keeps it (cbm_gbuf_upsert_node). A method claims nothing: its node is
49+
* receiver-qualified (<dir>.<Recv>.<Method>, #1913), and its w is `-`. w is 1 for
5050
* that declaration, 0 for the others of that name, x when two of them start
5151
* on that last line, and - for a value the extractor gives no node at all
5252
* (it gives one to the first name of a constant spec and of a parenthesis-
@@ -1511,9 +1511,11 @@ static void go_scan_method(go_scan_t *s, TSNode m) {
15111511
recv = "?";
15121512
recv_len = SKIP_ONE;
15131513
}
1514-
go_push_claim(s,
1515-
cbm_arena_sprintf(s->tmp, "M\t%.*s\t%.*s", (int)recv_len, recv, (int)len, name),
1516-
name, len, m);
1514+
/* #1913: a Go method node is receiver-qualified (<dir>.<Recv>.<Method>),
1515+
* so a method claims no flat name: w is `-`, and the method is found
1516+
* through its receiver (the member table), never through <dir>.<name>. */
1517+
(void)go_push_rec(
1518+
s, cbm_arena_sprintf(s->tmp, "M\t%.*s\t%.*s\t-", (int)recv_len, recv, (int)len, name));
15171519
}
15181520

15191521
/* The implied name of an embedded field: the type's own name, without

‎internal/cbm/extract_calls.c‎

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4493,6 +4493,24 @@ CBMInvocationDescriptor handle_calls(CBMExtractCtx *ctx, TSNode node, const CBML
44934493
}
44944494
}
44954495
}
4496+
// Go receiver-aware guard (same direction as the TS/JS flag above).
4497+
// Flag a selector call x.foo(). The Go AST cannot separate a method
4498+
// call on a value from a package-qualified call — but every selector
4499+
// call the Go LSP or the import/qualified registry strategies CAN
4500+
// place never reaches the weak short-name guards, so the flag only
4501+
// bites on unresolvable receivers (`f.Close()` on an os.File,
4502+
// `sha256.New()` behind an unindexed import), where a project-wide
4503+
// short-name match fabricates an edge to an unrelated project
4504+
// symbol sharing the name. Bare calls (helper()) keep
4505+
// is_method=false and resolve same-module/import paths as before.
4506+
if (ctx->language == CBM_LANG_GO &&
4507+
strcmp(ts_node_type(node), "call_expression") == 0) {
4508+
TSNode gofn = ts_node_child_by_field_name(node, TS_FIELD("function"));
4509+
if (!ts_node_is_null(gofn) &&
4510+
strcmp(ts_node_type(gofn), "selector_expression") == 0) {
4511+
call.is_method = true;
4512+
}
4513+
}
44964514

44974515
TSNode args = ts_node_child_by_field_name(node, TS_FIELD("arguments"));
44984516
/* tree-sitter-elixir attaches NO field name to a call's arguments

0 commit comments

Comments
 (0)