AnchorMap is a local deterministic CLI for auditing structural traceability between formal spec anchors and supported TypeScript repositories.
It shows what is observed in specs, what has been mapped explicitly by a human, what is structurally covered by supported local TypeScript edges, and whether the analysis is clean or degraded. AnchorMap is not a pruning system and is not a deletion-safety system.
AnchorMap v1.0 is distributed as the public npm package anchormap@1.0.0.
npm install -g anchormapThe installed command is anchormap. The v1.0 support matrix is:
- Linux x86_64
- macOS arm64
- Node.js 22 or newer
Other platforms are outside the v1.0 contract.
AnchorMap v1.0 is intentionally narrow:
- one repository root, which is the current working directory where the command starts;
- one TypeScript product tree under
product_root; - one or more spec roots containing Markdown or YAML specs;
- product files are
.tsfiles underproduct_root, excluding.d.ts; - supported local graph edges come from static TypeScript
importandexportdeclarations with relative string-literal specifiers.
The following are outside the v1.0 support boundary: monorepos, JavaScript
product files, TSX product files, declaration files as product files, TypeScript
path aliases, package specifier resolution, dynamic imports, require, and
repository-wide inference beyond the configured roots.
Start in a TypeScript mono-package repository:
.
├── .specify/
│ └── specs/
│ └── requirements.md
└── src/
├── index.ts
└── rules/
└── readme.ts
Example spec:
# DOC.README.PRESENT README presentExample product files:
// src/index.ts
import { checkReadme } from "./rules/readme";
export { checkReadme };// src/rules/readme.ts
export function checkReadme(path: string): boolean {
return path.endsWith("README.md");
}Initialize AnchorMap:
anchormap init --root src --spec-root .specify/specsThis creates anchormap.yaml:
version: 1
product_root: 'src'
spec_roots:
- '.specify/specs'
mappings: {}Add a human-approved mapping from an anchor to one or more seed files:
anchormap map --anchor DOC.README.PRESENT --seed src/index.tsRun the machine-readable scan:
anchormap scan --jsonscan --json writes one canonical JSON object to stdout on success. The root
keys are schema_version, config, analysis_health, observed_anchors,
stored_mappings, files, and findings.
Formatted for readability, the example above reports:
{
"schema_version": 1,
"config": {
"version": 1,
"product_root": "src",
"spec_roots": [".specify/specs"],
"ignore_roots": []
},
"analysis_health": "clean",
"observed_anchors": {
"DOC.README.PRESENT": {
"spec_path": ".specify/specs/requirements.md",
"mapping_state": "usable"
}
},
"stored_mappings": {
"DOC.README.PRESENT": {
"state": "usable",
"seed_files": ["src/index.ts"],
"reached_files": ["src/index.ts", "src/rules/readme.ts"]
}
},
"files": {
"src/index.ts": {
"covering_anchor_ids": ["DOC.README.PRESENT"],
"supported_local_targets": ["src/rules/readme.ts"]
},
"src/rules/readme.ts": {
"covering_anchor_ids": ["DOC.README.PRESENT"],
"supported_local_targets": []
}
},
"findings": []
}AnchorMap v1.0 exposes exactly three commands:
anchormap init --root <path> --spec-root <path> [--spec-root <path> ...] [--ignore-root <path> ...]anchormap map --anchor <anchor_id> --seed <path> [--seed <path> ...] [--replace]anchormap scan [--json]
init creates ./anchormap.yaml once. map creates or replaces explicit human
mappings in ./anchormap.yaml. scan reads ./anchormap.yaml and the
configured repository inputs; it never writes to disk.
Human-readable terminal output is not a stable contract in v1.0. Use
scan --json for the guaranteed machine interface.
Exit-code overview:
0: success, including completed analyses that emit findings in JSON;1: write failure or internal failure;2:anchormap.yamlis missing, unreadable, invalid, or violates config rules;3: repository inputs outsideanchormap.yamlcannot be read, decoded, parsed, indexed, or otherwise inspected as required;4: unsupported command, option, or option combination.
For scan --json, success writes JSON to stdout and leaves stderr empty, even
when the JSON contains findings. On exit codes 1 through 4, stdout is empty
and no JSON is emitted.
anchormap.yaml is the only AnchorMap-owned persistent source of truth. It
stores stable config and explicit human mappings only; it does not store caches,
derived graph data, candidates, classifications, history, or metrics.
covering_anchor_ids reports structural reachability from usable mappings under
the supported local TypeScript rules. It is not ownership proof.
untraced_product_file means a product file was not reached by any usable
mapping when the analysis was clean enough to emit that finding. It does not
mean dead code, and it does not authorize removing the file.
analysis_health = clean means no degrading findings were emitted. It does not
mean every product file is mapped.
For the full machine contract, see docs/contract.md.