The #sym: reference syntax (SPEC v1)
A #sym: reference is a standard relative markdown link whose fragment names a symbol inside the target source file. It renders and clicks like any other link on GitHub, and symtether verifies each reference against the code.
Canonical form
[link text](<relative-path>#sym:<dotpath>)
[link text](<relative-path>#sym:<kind>:<dotpath>)<relative-path>is a standard markdown relative path to a source file, resolved relative to the markdown file's own directory (identical to GitHub rendering semantics). Paths beginning with/resolve from the repository root. The repo root is the nearest ancestor containing.git, or the working directory when there is none.<dotpath>is one or more identifiers joined by., e.g.ApiClient.fetchData. Each segment must match[A-Za-z0-9_$]+and is compared case-sensitively.<kind>is an optional disambiguator from a closed set:fn,class,type,const. (regionis reserved for future versions.) An unknown kind is a lint error, not ignored.
Examples:
[fetch pattern](../src/api/client.ts#sym:ApiClient.fetchData)
[config parsing](src/config.ts#sym:fn:parseConfig)
[shared types](/packages/core/src/types.ts#sym:type:AgentSkill)Matching semantics
The dotpath is a suffix match against the definition's nesting chain, not a language-exact qualified name.
- The resolver extracts all named definitions in the target file as
(name, kind, nesting-chain, range)tuples. - A ref matches a definition if the dotpath segments equal the trailing segments of that definition's nesting chain.
ApiClient.fetchDatamatches a methodfetchDatanested in classApiClient, even ifApiClientis itself inside a namespace. - If
<kind>is present, the matched definition's kind must also map to it. - Exactly one match passes. Zero matches is broken. Two or more matches is ambiguous, an error instructing the author to qualify further by adding a parent segment or a kind.
Compatibility (lenient) forms, read-accepted and never written
On links whose target path resolves to a non-markdown source file, these fragments are accepted with identical semantics and reported with a compat note:
#Symbol(bare)#Type.method(bare dotpath)
symtether fix --canonicalize rewrites them to #sym: form. Fragments on links targeting markdown files are heading anchors and are never treated as symbol refs.
Out of scope
Line numbers or ranges (#L10), query parameters, version/commit pins, multiple symbols per link, wildcards, regex.
Where refs are recognized
- Inline links and reference-style links (
[text][id]+[id]: path#sym:X) in.mdfiles. - Ignored: links inside fenced code blocks and inline code spans, image links (
![]()), autolinks, external URLs (any scheme),mailto:, and pure-fragment links (#heading). <!-- symtether-disable-next-line -->suppresses checking for refs on the following line.<!-- symtether-disable -->and<!-- symtether-enable -->suppress and restore checking for a block.