Skip to content

ADR-0019: Import-path aliases as external action identifiers

  • Status: proposed
  • Date: 2026-04-13
  • Deciders: @Aksem
  • Tags: actions, api, architecture

Context

ADR-0006 establishes shared action-definition types as the identity contract for handler-to-handler invocation inside Python environments. That contract works because all participating environments share the same Python package and can reference the type directly.

External callers — the VS Code extension, MCP server, and CLI — cannot use Python types. They communicate over JSON-RPC and must identify actions by a string. Currently these callers use a project-local name (e.g. "lint"), which does not reflect the type-level contract and is ambiguous across projects. The goal is to migrate to a string identity that corresponds to the action-definition type.

Two string forms can represent an action-definition type:

  • Import-path alias — the import path an extension author re-exports as their public API (e.g. finecode_extension_api.actions.LintAction). This is already the value users write in the source field of project configuration.
  • Canonical path — the class's actual definition location, derived from __module__ and __qualname__. This path is globally unique without normalization but reflects internal module structure rather than the public API surface.
  • ADR-0006 — establishes the type-level identity rule this ADR extends to the string domain.
  • ADR-0007 — ensures at most one registration per action type per project, so alias normalization is unambiguous.

Decision

External callers identify actions by their import-path alias — the same string written in the source field of project configuration. FineCode resolves aliases to the canonical path internally; any valid import path that resolves to the registered action class is accepted.

This establishes the following rules:

  • The action-definition class is the identity. Any import path that resolves to the same class as the registered action is a valid identifier. FineCode normalizes aliases to a canonical form for internal comparison.
  • Canonical paths are an internal concern. Callers must not rely on paths derived from __module__ or __qualname__ directly. These reflect internal module structure and may change when an extension reorganizes its codebase without altering its public API.
  • Users should prefer the highest-level import path the extension documents as its public API. When multiple aliases resolve to the same class, the more general one (e.g. finecode_extension_api.LintAction over finecode_extension_api.actions.LintAction) is less exposed to internal reorganization. The criterion is the extension author's documented stable surface, not shortest path.

Consequences

  • Consistency with configuration. The same import-path string the user writes in pyproject.toml is the string they use in API calls. No new identifier form is introduced.
  • Stability under internal reorganization. When an extension author moves a class to a different internal module but preserves the public re-export, external callers are unaffected. Canonical paths do not provide this guarantee.
  • Normalization is required. Because multiple aliases may refer to the same class, FineCode must normalize incoming identifiers before comparing. This is a resolution step that does not exist when canonical paths are used directly.
  • Callers must use documented public aliases. An alias that resolves correctly today may stop resolving if the extension reorganizes its internals. Only aliases the extension author documents as stable should be used.

Alternatives Considered

Canonical paths only (__module__.__qualname__). Rejected because canonical paths expose private module structure, diverge from what users write in configuration, and break whenever an extension reorganizes its internal layout even when the public API is unchanged.

  • Extends ADR-0006 — applies the type-level identity rule to the string domain for external callers.
  • Depends on ADR-0007 — single registration per action type makes alias normalization unambiguous.