ADR-0005: Zero-based line numbers and ResourceUri fields in action payloads and results¶
- Status: accepted
- Date: 2026-03-20
- Deciders: @Aksem
- Tags: actions, conventions
Context¶
Action payload and result types that carry source-code locations must agree on two conventions: how line numbers are represented and how resource locations are represented.
Line numbers. LSP uses 0-based Position.line throughout. Test runner CLIs
and linters typically emit 1-based line numbers. A mismatch between the two
means that whoever builds the result (the handler) and whoever consumes it (e.g. the
LSP server) must each know which convention is in use.
Resource locations. Action payloads and results cross process boundaries
and should remain stable across languages and transports. Using runtime-specific
objects such as pathlib.Path in boundary DTOs leaks implementation details
into the contract. A semantic ResourceUri type, serialized as a URI string,
avoids this and leaves room for future non-local resources.
This decision applies to all actions that expose source-code locations in their payload or result schema.
Related ADRs Considered¶
None — no existing ADR covers payload/result field conventions for source-code locations.
Decision¶
-
Line numbers in payload and result fields are 0-based, consistent with
Position.linein the Language Server Protocol. Handlers that read 1-based line numbers from CLI output must subtract 1 before populating a field. Display code that shows lines to users must add 1. -
Resource locations in payload and result fields use
ResourceUrivalues, notpathlib.Pathobjects.ResourceUriis serialized as a URI string. Local files usefile://URIs; future non-local resources may use other URI schemes. This keeps the field type simple across transports, languages, and runtimes.
Consequences¶
- Handlers bear the conversion cost. Handlers that consume 1-based CLI output subtract 1; they do not pass the raw value through. This is a one-line transformation and the correct place to isolate runner-specific quirks.
- Display code adds 1. Any code that renders a line number to a user (terminal output, hover text) must add 1 to recover the 1-based number a developer expects to see.
- No Path objects in payload or result fields. Producers populate location
fields with
ResourceUrivalues serialized as URI strings. Consumers that need a localPathmay derive one only when the URI scheme isfile. - Future-proof resource model. The contract is not limited to local filesystem paths, so future handlers can report locations for non-file resources without redefining the result schema.
- Consistency across actions.
LintMessage.range,TestCaseResult.line, andTestItem.lineall follow the same source-location convention, and the same rule applies to any future action payload or result type that carries source-code locations rather than requiring per-action documentation.