Skip to content

can:// module ids gain a manifest-derived module segment #92

Description

@rahlk

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/Gradle artifactId, [project] name, package.json name — 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.

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-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-pythonrelative_to(self.project_dir) in codeanalyzer/core.py
  • codeanalyzer-typescriptpath.relative(root, abs) in src/utils/fs.ts
  • codeanalyzer-goto verify, has source but unread
  • python-sdk — id-keyed half of the Java index (_callables); the qualified_name-keyed half is unaffected. Pin bump gates consumability, see Bump codeanalyzer-java pin once the BuildProject fixes release python-sdk#418
  • 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

  1. keystone grammar recorded in cldk-devtools (no release)
  2. codeanalyzer-java implements + releases
  3. python-sdk pin bump + release
  4. codeanalyzer-python, codeanalyzer-typescript, each with its SDK pin bump
  5. docs both fronts

Between 2 and 4 analyzers in one polyglot graph disagree about whether a module prefix is present. Keep that window short.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions