You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
A module's can:// id gains a segment naming the module as its own manifest declares it — Maven/Gradle artifactId, [project] name, package.jsonname — between the language segment and the intra-module path:
before can://daytrader/java/src/main/java/org/apache/.../RunStatsDataBean.java
after can://daytrader/java/daytrader-web-service/src/main/java/org/apache/.../RunStatsDataBean.java
So pointing --input at one service repo names that service in the id, with no staging directory and without pointing --input at a parent that sweeps in sibling repos. The prefix is manifest-derived rather than path-derived so it survives directory renames and a differently-laid-out CI workspace.
symbol_table keys are unchanged — they stay the true --input-relative path. The prefix applies only where exactly one manifest directory claims it; a contested prefix is applied to neither claimant, with a warning. Both rules exist for the same reason: uniqueness, which a path guarantees and an artifactId does not.
This re-opens the grammar that #39 declared settled when it was closed NOT_PLANNED in August. Deliberate, and recorded in the spec's §10 with the differences from that larger design ( <service> replacing <app>, --app-name renamed, per-service duplication, a breaking 2.1.0 erratum — none of which this does).
#36 regains a prerequisite as a result. Its August unblocking followed directly from the grammar being settled, so freezing the contract should be sequenced after this lands, not before.
Affected repos
Parity clause applies — all analyzers move together or the language-neutral artifact / @external merge targets stop lining up with the code nodes beside them.
codeanalyzer-java — reference implementation, first to land and release
codeanalyzer-python — relative_to(self.project_dir) in codeanalyzer/core.py
codeanalyzer-typescript — path.relative(root, abs) in src/utils/fs.ts
codeanalyzer-go — to verify, has source but unread
typescript-sdk — pin chain to verify, no local checkout
docs (both fronts) and the keystone reference in cldk-devtools
Does not fix
codellm-devkit/codeanalyzer-java#269 — a single analysis spanning source roots that declare the same fully-qualified type binds every caller to the last root, silently. This change makes a bundled tree addressable, not correctly resolved. Anyone moving to one-run-per-tree because ids now distinguish modules still needs the copies deduplicated in source or #269's caller-local resolution.
Release sequence
keystone grammar recorded in cldk-devtools (no release)
codeanalyzer-java implements + releases
python-sdk pin bump + release
codeanalyzer-python, codeanalyzer-typescript, each with its SDK pin bump
docs both fronts
Between 2 and 4 analyzers in one polyglot graph disagree about whether a module prefix is present. Keep that window short.
Spec:
docs/design/specs/2026-09-17-manifest-derived-module-prefix.md(in review: #91)Summary
A module's
can://id gains a segment naming the module as its own manifest declares it — Maven/GradleartifactId,[project] name,package.jsonname— between the language segment and the intra-module path:So pointing
--inputat one service repo names that service in the id, with no staging directory and without pointing--inputat a parent that sweeps in sibling repos. The prefix is manifest-derived rather than path-derived so it survives directory renames and a differently-laid-out CI workspace.symbol_tablekeys are unchanged — they stay the true--input-relative path. The prefix applies only where exactly one manifest directory claims it; a contested prefix is applied to neither claimant, with a warning. Both rules exist for the same reason: uniqueness, which a path guarantees and anartifactIddoes not.Supersedes #39
This re-opens the grammar that #39 declared settled when it was closed NOT_PLANNED in August. Deliberate, and recorded in the spec's §10 with the differences from that larger design (
<service>replacing<app>,--app-namerenamed, per-service duplication, a breaking 2.1.0 erratum — none of which this does).#36 regains a prerequisite as a result. Its August unblocking followed directly from the grammar being settled, so freezing the contract should be sequenced after this lands, not before.
Affected repos
Parity clause applies — all analyzers move together or the language-neutral
artifact/@externalmerge targets stop lining up with the code nodes beside them.codeanalyzer-java— reference implementation, first to land and releasecodeanalyzer-python—relative_to(self.project_dir)incodeanalyzer/core.pycodeanalyzer-typescript—path.relative(root, abs)insrc/utils/fs.tscodeanalyzer-go— to verify, has source but unreadpython-sdk— id-keyed half of the Java index (_callables); thequalified_name-keyed half is unaffected. Pin bump gates consumability, see Bump codeanalyzer-java pin once the BuildProject fixes release python-sdk#418typescript-sdk— pin chain to verify, no local checkoutdocs(both fronts) and the keystone reference incldk-devtoolsDoes not fix
codellm-devkit/codeanalyzer-java#269 — a single analysis spanning source roots that declare the same fully-qualified type binds every caller to the last root, silently. This change makes a bundled tree addressable, not correctly resolved. Anyone moving to one-run-per-tree because ids now distinguish modules still needs the copies deduplicated in source or #269's caller-local resolution.
Release sequence
cldk-devtools(no release)codeanalyzer-javaimplements + releasespython-sdkpin bump + releasecodeanalyzer-python,codeanalyzer-typescript, each with its SDK pin bumpdocsboth frontsBetween 2 and 4 analyzers in one polyglot graph disagree about whether a module prefix is present. Keep that window short.