Skip to content

can:// ids gain a <service> segment; collapse <app> (schema 2.1.0) #91

Description

@rahlk

Spec: codellm-devkit/.githubdocs/design/specs/can-uri-service-segment.md
Coordination: codellm-devkit/.github#39

Problem

src/schema/v2/emit.ts:350 builds the application root with the language outermost:

const appId = `can://${LANGUAGE}/${appName}`;

so every durable id is can://typescript/<app>/<file>/<type>/<sig>, with no deployment
dimension. A polyglot microservice therefore has no single id root — its TypeScript and Python
halves land under unrelated authorities — and cocoa has had to build one outside the schema
(cocoa/system/facts.py:39 wraps our id as fn:<service>/can://…).

Per the spec, <service> becomes the outermost segment and <app> collapses into it:

before  can://typescript/<app>/<file>/<type>/<sig>
after   can://<service>/typescript/<file>/<type>/<sig>

Scope boundary

This repo only. Does not add cross-service edges (no RPC/HTTP call family — Epic E), does not
touch the keystone grammar docs, does not touch cocoa, and does not touch codeanalyzer-python
(its own issue). The can:// scheme name is settled and not in scope.

Does not attempt to reconcile the two known sibling divergences recorded in the
codeanalyzer-dotnet spec — UTF-16 vs UTF-8 span offsets, and unprefixed vs per-language Neo4j
labels. Both are real, both make this repo the outlier, and both are their own design session.

Goals

  • src/schema/v2/emit.ts:350 — service becomes the outermost segment; <app> removed
  • src/schema/v2/model.ts:39 — the id: string; // can://<lang>/<app> comment follows
  • src/cli.ts:19--app-name <name>--service <name>, same default (input dir name);
    src/options/options.ts:15 appName renamed with it
  • src/build/neo4j/schema.tsSCHEMA_VERSION"2.1.0"; CanNode keys follow the ids
  • homeExternals (emit.ts:301) — verify @external ids still compose from appId with no
    logic change: can://<service>/typescript/@external/<module>/<name>
  • Anonymous-callback ordinal ids (<enclosing-can-id>@<line>:<col>) unchanged
  • v2 tests + test/neo4j-schema.test.ts conformance updated

Caveats and known risks

  • The version number understates the break. 2.1.0 is MINOR for a change that rewrites every
    durable id and the CanNode MERGE key — this repo's own rule in src/build/neo4j/schema.ts
    says MAJOR on a renamed key. Deliberate erratum, valid only because no consumer holds a
    can:// id today (typescript-sdk is pre-v2, zero references). Not precedent later.
  • Persisted Neo4j graphs need a full re-ingest, not an incremental MERGE.
  • Shared code is analyzed once per service by design: one run per service (spec D5).
  • Renaming --app-name is a CLI break for existing callers. Whether to keep a deprecated
    alias is an open call the spec does not decide.
  • Must land in lockstep with codeanalyzer-python's equivalent change; cocoa is gated on both.

Definition of done

  • A no-flag run on a TS project emits can://<dir-name>/typescript/src/… — verified on a
    real run, not an asserted shape
  • --service checkout emits can://checkout/typescript/src/cart.ts/CartService/checkout(userId)
  • No emitted id contains an <app> segment distinct from the service
  • External library targets resolve as can://<service>/typescript/@external/<module>/<name>
    and every callee backfilled at L2 points at a resolvable id
  • Every edge endpoint resolves — call_graph, extends_ids/implements_ids,
    param_in/param_out — with zero dangling references
  • Ordinal ids below the callable unchanged, including anonymous callbacks
  • schema_version reads "2.1.0" in both the JSON envelope and the Neo4j contract
  • test/neo4j-schema.test.ts passes — the emitter produces no undeclared label,
    relationship, or property

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