Spec: codellm-devkit/.github → docs/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
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
Spec:
codellm-devkit/.github→docs/design/specs/can-uri-service-segment.mdCoordination: codellm-devkit/.github#39
Problem
src/schema/v2/emit.ts:350builds the application root with the language outermost:so every durable id is
can://typescript/<app>/<file>/<type>/<sig>, with no deploymentdimension. A polyglot microservice therefore has no single id root — its TypeScript and Python
halves land under unrelated authorities — and
cocoahas had to build one outside the schema(
cocoa/system/facts.py:39wraps our id asfn:<service>/can://…).Per the spec,
<service>becomes the outermost segment and<app>collapses into it: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 touchcodeanalyzer-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-dotnetspec — UTF-16 vs UTF-8 span offsets, and unprefixed vs per-language Neo4jlabels. 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>removedsrc/schema/v2/model.ts:39— theid: string; // can://<lang>/<app>comment followssrc/cli.ts:19—--app-name <name>→--service <name>, same default (input dir name);src/options/options.ts:15appNamerenamed with itsrc/build/neo4j/schema.ts—SCHEMA_VERSION→"2.1.0";CanNodekeys follow the idshomeExternals(emit.ts:301) — verify@externalids still compose fromappIdwith nologic change:
can://<service>/typescript/@external/<module>/<name><enclosing-can-id>@<line>:<col>) unchangedtest/neo4j-schema.test.tsconformance updatedCaveats and known risks
durable id and the
CanNodeMERGE key — this repo's own rule insrc/build/neo4j/schema.tssays MAJOR on a renamed key. Deliberate erratum, valid only because no consumer holds a
can://id today (typescript-sdkis pre-v2, zero references). Not precedent later.MERGE.--app-nameis a CLI break for existing callers. Whether to keep a deprecatedalias is an open call the spec does not decide.
codeanalyzer-python's equivalent change;cocoais gated on both.Definition of done
can://<dir-name>/typescript/src/…— verified on areal run, not an asserted shape
--service checkoutemitscan://checkout/typescript/src/cart.ts/CartService/checkout(userId)<app>segment distinct from the servicecan://<service>/typescript/@external/<module>/<name>and every
calleebackfilled at L2 points at a resolvable idcall_graph,extends_ids/implements_ids,param_in/param_out— with zero dangling referencesschema_versionreads"2.1.0"in both the JSON envelope and the Neo4j contracttest/neo4j-schema.test.tspasses — the emitter produces no undeclared label,relationship, or property