Tags give the ability to mark specific points in history as being important
-
v0.0.21
9a9fc992 · ·codemap 0.0.21 — two gates that claimed more confidence than they had R1-C62 — a contract rule naming something absent was counted as enforced. Rename a layer, forget codemap.toml, and the gate printed a green tick over a rule that could no longer fire. The inertness stays (writing a contract ahead of the code is a documented, legitimate use); the count now carries declared vs applicable where they differ, the absent names are listed, `applicability` is in the structured answer always, and `no_phantom_rules = true` makes an absent name a failure for those who want it. The question came from outside the project — a third-party repo about requirements that stop being true, run rather than read. R1-C63 — the answer has a version now. SCHEMA_VERSION versions the artifact and said nothing in 0.0.20, correctly: the graph was byte-identical while the gate's output changed completely. On a text diff that is the same picture as the hash-order defect filed four days earlier, and only a hand-written message told them apart. ANSWER_FORMAT starts at 1, travels as a trailer on markdown answers and as a field in every serve/MCP envelope, and a pinned hash over six rendered surfaces refuses to let the shape move silently. Verified from PyPI against 0.0.20 on trees carrying the shape of each defect, under a fixed PYTHONHASHSEED: phantom contract 0.0.20: layered (3), independent (1), forbidden (1) 0.0.21: layered (3 declared, 0 applicable), … + names + no_phantom_rules 0.0.20: exit 0 → 0.0.21: exit 2 sound contract one added line: the trailer consumer's live tree one added line: the trailer; verdict exit 0 → exit 0 graph nodes and edges hash identical, schema 0.13 → 0.13 Schema 0.13, tenth release running. Suite 972 → 990. -
v0.0.20
58bcb63b · ·codemap 0.0.20 — the unit of a cycle answer is the tangle Schema 0.13, unchanged for the ninth release running. The last of the four findings from the axis-B4 run over pytest, attrs and Pillow, and the only one that was a metric rather than a bug. Counting simple cycles counts paths through a knot: 78 modules of a real package produced 464 109 of them, and a 1632-line report took 10.3 s to print twenty. The unit is now the tangle — the group of modules that cannot be separated — with one example cycle, the edge holding it together, and its independent loops (E - V + 1), which preserves what the old count was for: two loops sharing a module are still two problems. Verified from PyPI with both published versions on one tree: a 7-module knot reads 115 cycles on 0.0.19 and "1 tangle, 7 modules, 15 independent loops" on 0.0.20. Changes the shape of an answer consumers read, so it ships alone. Suite 972.
-
v0.0.19
825355c5 · ·codemap 0.0.19 — three packages by other people, three defects our own trees could not show Schema 0.13, unchanged for the eighth release running. Everything here came from one afternoon of axis B4: pointing codemap at pytest, attrs and Pillow — code written by neither its author nor its consumers — with the expectations committed before the run. - R1-C55 an override is reached through its base, so it cannot be graded confidently dead (40 of 63 `high` candidates on Pillow were wrong). - R1-C56 a `.pyi` is never executed, so it cannot close an import cycle (Pillow's only hard cycle was fabricated by one). - R1-C57 the facade layout crashed the build, reported a public surface of one symbol for a package that re-exports 90, and was the one report the empty-import-graph warning did not reach. Verified from PyPI with both published versions on one tree carrying all three shapes. Suite 938 -> 961.
-
v0.0.18
7071b33e · ·codemap 0.0.18 — narrowings declare themselves, and one graph renders one way Two items, one habit. Schema 0.13, unchanged for the seventh release: the same tree built by 0.0.17 and by 0.0.18 from PyPI is byte-identical in nodes and edges, only provenance differs, so a pin bump re-extracts nothing. - R1-C53: eight of the previous twelve fixes were one defect — an answer narrower than it looks, silent about it. Seven classes of narrowing enumerated, all 31 ops in a published matrix, two guards reading the ops' own source. Four undeclared ones closed, the largest being `columns` returning 331 of 1057 keys as a bare list. - R1-C54: the printed cycle chain was whichever rotation the hash chose — three renderings of one graph. Canonicalised at the source, because measuring found three consumers drifting and one of them was the structured MCP answer, not the gate that was reported. Verified from PyPI, both versions on one tree carrying the shape of both defects: check under 8 hash seeds 0.0.17: 3 distinct renderings (5/2/1) 0.0.18: 8 of 8 identical columns / communities 0.0.17: no declaration at all 0.0.18: filter {basis, total, dropped} · scope {root, judged, not_judged} The second item found the axis the first had missed: an answer can be complete, declared, and still differ between runs. A matrix is complete only along the axes someone thought of. -
v0.0.17
985928ea · ·codemap 0.0.17 — a library's entry point, a filter that declares itself, a diff that judges the package Three defects, all found by the dogfood target in one message while verifying a measurement of ours on their own tree (issue #19). Schema 0.13, unchanged for the sixth release: the same tree built by 0.0.16 and 0.0.17 from PyPI is byte-identical in nodes and edges, only provenance differs, so a pin bump re-extracts nothing. - R1-C50: `entry_points` required in-degree zero across the whole graph, so a library's public API was disqualified by being used from tests — and the deep tier, resolving more, answered emptier. In-degree is now counted within the root, an entry names the outside roots that enter it, and the empty answer says which kind of empty it is. - R1-C51: the route-grade filter answered `[]` without saying a filter had run. The envelope now carries a `filter` block always, with the composition of the unfiltered answer, so an empty result reads as "called, only through routes you excluded". - R1-C52: `diff` counted consumer-root public symbols as API — 40 of 47 in their release gate were test functions. It compares one root now and names what it did not judge. Verified from PyPI, both versions on one tree: "0 of 0 entry points" -> "1 of 1"; a consumer's new public function "1 added" -> "0 added" with the not-judged line; the filter block absent -> present.
-
v0.0.16
48d032f7 · ·codemap 0.0.16 — where a change lands in a scenario, and what found each edge Schema 0.13, unchanged for the fifth release, and no graph bytes move: the same tree built by 0.0.15 and by 0.0.16 from PyPI is byte-identical in nodes and edges, only provenance differs. Consumers bump the pin and re-extract nothing. - R1-C40: `report impact` names the flows a change lands on and the step it lands at (one reverse BFS; agreed with the forward walk on 1324 + 252 measured pairs, 0 mismatches). Reached, not broken — the graph knows the symbol is on the path. - R1-C39: the `extras.resolution` vocabulary is closed and graded (exact / inferred / heuristic), `callers`/`callees` take min_confidence, `stats` reports the mix. The grade is derived, not stored — which is why the artifact does not move. Both items came from our own reading of a neighbouring tool, not from a filed issue, and both needed less than the backlog entry that proposed them.
-
v0.0.15
e513a366 · ·codemap 0.0.15 — a rule that ran names itself Schema 0.13 unchanged, no graph bytes. `check`'s passing line lists `no_type_only_cycles` like every other enforced rule; a contract holding only that rule no longer prints "Rules enforced: ." (R1-C49-f1, issue #18).
-
v0.0.14
2f61e547 · ·codemap 0.0.14 — a cycle has three kinds, and the second rule stops refusing the typing idiom Schema 0.13 unchanged, no graph bytes move. `no_lazy_cycles` narrows to cycles closed by a function-local import; a cycle closed only by an import under `if TYPE_CHECKING:` is a third kind with its own opt-in rule `no_type_only_cycles` (R1-C49, issue #18).
-
v0.0.13
58cd8496 · ·codemap 0.0.13 — a third import scope, and a merge independent of arrival order Schema 0.13 unchanged. An import under `if TYPE_CHECKING:` carries scope: type_checking and is not an eager edge (R1-C48, issue #18); the --repeat merge breaks ties by a total order (D10, issue #17).
-
v0.0.12
311456d9 · ·codemap 0.0.12 — an empty answer says which kind of empty it is; the chain samples N times A symbol the graph does not hold answers `resolved.found: false` and `risk: unknown` on every resolving op, instead of an envelope identical to "found, nothing references it"; `query` by full id opens the dossier. `--incremental --repeat N` and `watch --repeat N`: N is a property of the chain, sampled at the base, the fallback and every tick's recompute — measured on twenty real commits against the periodic full rebuild it replaces. Schema unchanged (0.13).
-
v0.0.11
4c11930f · ·codemap 0.0.11 — build N samples and say what varied; a name defined twice is a certain finding `codemap build --deep --repeat N`: N independent samples, each in a fresh interpreter, unioned per edge class; `extras.seen` on edges not in every run, `provenance.samples` on every build. The deep-tier note names the measured share (a real edge in 126 of 168 full builds) and what N does to it. Shadowed definitions are walked once, recorded as `extras.shadows`, and reported as certain in `report dead-code`. Schema unchanged (0.13).
-
v0.0.10
a392928a · ·codemap 0.0.10 — a graph that was partly carried over now says so Schema 0.13, unchanged. Disclosure only: provenance.incremental on every build (false included — a missing field is unknown, not full), an incremental_deep_splice note on a deep graph carrying spliced regions, and the correction that the deep tier's flap moves jedi-resolved edges generally, not calls edges only. Verified from PyPI in clean venvs outside any checkout, both directions: - an incremental deep build reports incremental=true and prints the note, on stderr and in a rendered report; a full deep build reports false and prints nothing; the fast tier stays silent on both counts; - against 0.0.9 on the same tree, the fast graph is byte-identical apart from the single new key, with the same scope_id (sha256:e0e64d52d0e6da7b0) and the same 2869 nodes / 8408 edges — the change is inert wherever it has nothing to say.
-
v0.0.9
b21dff16 · ·codmap 0.0.9 — a deep graph now says what kind of artifact it is Schema unchanged (0.13). Nothing about what codemap extracts changes; what changes is disclosure. The deep (jedi) tier is not byte-stable: ten builds of an unchanged tree produced two distinct artifacts here, and on a larger external tree one build in seven lost a real call edge of 9524. That limit was known — measured at R1-C9 — and lived in a comment in a CI workflow, while README said "deterministic" with no tier attached and the one doc that named it gave a cause this measurement refutes. Every deep graph now carries a note with the measured numbers, and `diff` prints the noise floor above the verdict when both sides are deep. Five external explanations were tested at ten runs each and refuted; the mechanism is jedi's per-script execution budget, and why it differs by one execution between processes is stated as unknown rather than guessed. Verified from PyPI, outside any checkout: the note appears on --deep and not on fast, and the caveat appears on a deep/deep diff and not on a fast/fast one.
-
v0.0.8
8d9c1383 · ·codmap 0.0.8 — the manifest now describes the input the graph was built from Schema unchanged (0.13). In git mode the input manifest enumerated the tracked set while the extractor walked the filesystem, so a module that exists and has not been `git add`ed — or one .gitignore excludes — was in the graph, absent from scope.files, and moved scope_id not at all. Since scope_id is the cache key for --incremental and the watch probe, --incremental answered "unchanged: 0 module(s) recomputed" over a file that had just grown a new symbol. Enumeration now adds `git ls-files --others --exclude-standard`; membership is checked rather than trusted, with gitignored files named rather than adopted; the result rides in provenance.inputs. Verified from PyPI, outside any checkout, against the scenario the release exists for: the untracked module enters the manifest with tracked: false, scope_id moves, and --incremental recomputes it. A clean tree resolves to the identical scope_id under 0.0.7 and 0.0.8, so no pinned identity moves.
-
v0.0.6
c8350eae · ·codemap 0.0.6 — checks that had never been shown the thing they must reject Evidence rather than behaviour: one new item (a warm server that says when it is running code the installed distribution has moved past) and three that change what is known about the tool rather than what it does — every contract rule mutation-tested on a real tree, the target guard's decision tested directly, and a defect measured on a flat layout where it merged two trees rather than replacing one. Schema 0.13, unchanged; no rebuild needed. Published as codmap 0.0.6. Superseded within the day by 0.0.7: the new diagnostic could not fire as shipped.
-
v0.0.7
364fd765 · ·codemap 0.0.7 — the one thing 0.0.6 added, now actually reachable R1-C38-f1: `tool_restart_needed` compared a cached version with itself, so a warm server never warned that it was running superseded code. The installed side is now read fresh per call, and the regression test changes only the installation. Schema 0.13, unchanged. Verified on the published wheel by driving the scenario the feature exists for: serve, change the installation underneath, ask — reported on both `stats` and `reload`. Published as codmap 0.0.7.
-
v0.0.5
9523dc1d · ·codemap 0.0.5 — three answers that were well-formed and wrong Correctness release, no schema change (graphs stay 0.13; rebuild anyway, two fixes change what a graph says). - R1-C33 the declared signature travels with the `query` dossier - R1-C34 the stored signature dropped parameter kind (14.3% of codemap's own functions, 16.3% of bquant's), which had silently disabled three apidiff rules - R1-C35 a gate that found no contract did not say where it looked, nor that this exits 0 - R1-C36 a build could analyse a different package with the same name, with exit 0 and a complete graph of the wrong code Verified from PyPI in a clean venv outside any checkout, from a working directory holding a package of the same name as the target: the build described the directory it was given, the graph carries no absolute paths, the signature renders `*args` and the keyword-only marker, the class dossier carries its constructor, and `check` names the file it searched. 713 tests, 2 skipped. -
v0.0.4
45de657c · ·codemap 0.0.4 — schema 0.13 Nine Fixed entries since 0.0.3, and all but one came from a second real user's tree: R1-C28 (limit envelope), R1-C29 (lazy imports are dependencies, and a cycle has two kinds), R1-C30 + f1 + f2 (calls through a function-local import, through a re-export, and a gate that judged a subset in silence), R1-C31 (one path origin per graph), R1-C32 (report --format json), M3.2 + f1 (the watch loop, with an adaptive debounce). Schema 0.12 -> 0.13: a repo-scoped graph now has one origin for its paths. Rebuild those; a single-package graph is byte-identical. Published as codmap 0.0.4; verified from PyPI in a clean venv outside any checkout: schema 0.13, provenance.tool {"name": "codemap", "version": "0.0.4"} with no commit, which is the correct no-checkout answer. -
v0.0.3
4c2f8c6f · ·codmap 0.0.3 — the first published release First release on PyPI, as the distribution `codmap` (the command, the import and the repository stay `codemap`; the bare name was taken). Ships everything that had accumulated since 0.0.2: flat-layout support, source-visible references, the deep tier as a union with the fast one, graph provenance (schema 0.12), test mapping, hard-Python robustness, and M20 — CI, honest package metadata, and a measured Python range. Verified from PyPI into a clean venv, run outside any source tree.
-
v0.0.2
68a0908e · ·codemap v0.0.2 — first internal cut (schema 0.11, 363 tests; attribute-access edges + incremental rebuild). Not published to PyPI.