narrativetrace-glossary
The domain glossary of a repository: one checked-in glossary.json that is simultaneously the
translation dictionary, the reviewable domain documentation, and the vocabulary norm that clarity
diagnostics enforce (ADR-012).
The Java module narrativetrace-glossary. Platform mapping: Java packages become dotted
module-path prefixes, so a bounded context owns acme.billing, not com.acme.billing.
from narrativetrace_glossary import read_glossary_json, write_glossary_json
glossary = read_glossary_json(Path("glossary.json").read_text(encoding="utf-8"))
Path("glossary.json").write_text(write_glossary_json(glossary), encoding="utf-8")
Identifiers become glossary phrases through the normalizer, and the module path of the traced code picks the bounded context that owns them:
from narrativetrace_glossary import method_candidates, normalize_phrase, resolve_context
normalize_phrase("open_account_with_overdraft") # "open account with overdraft"
method_candidates("openAccountWithOverdraft") # verb phrase + "account with overdraft"
resolve_context(glossary, "acme.billing.overdraft_service") # "billing"
Every spelling of one concept converges to a single phrase, so matching against terms and aliases
always happens on the normalized form. Context prefixes match on dot boundaries — acme.billing
owns acme.billing.overdraft but never the sibling acme.billingx — the longest match wins, and
an unmatched path falls back to _unassigned, so harvesting works with zero configuration.
The normalizer rejects anything that is not a single code identifier (blank, underscore-only, or
whitespace-carrying input raises ValueError): a normalized phrase is term identity, so a
non-canonical one would corrupt a glossary key.
The writer is deterministic by construction — contexts sorted by name, terms in (context, term)
order, fixed key order, 2-space indent, trailing newline — so a run that observes no new vocabulary
leaves the committed file byte-identical.
Harvesting a run into the glossary
harvest_traces observes captured trace trees; merge_harvest folds those observations into the
committed glossary. Trace nodes carry a simple class name, so the caller supplies module_of to
say which module declares it — production code passes type(target).__module__, tests pass a dict
lookup. A name it cannot answer for resolves to _unassigned.
from narrativetrace_glossary import harvest_traces, merge_harvest, write_glossary_json
observed = harvest_traces(trees, glossary=glossary, module_of=modules.get)
result = merge_harvest(glossary, observed)
Path("glossary.json").write_text(write_glossary_json(result.glossary), encoding="utf-8")
Harvest sources are method names (the verb phrase plus the object noun phrase), parameter names,
class names with a role suffix stripped, and the type name of whatever a node threw. Names that are
no identifier — synthetic nodes like <launcher> or fire-and-forget — are skipped silently;
harvesting is best-effort by design. Narration templates are never harvested from a live trace:
they hold interpolated runtime values there.
The merge is additive-only and idempotent, both property-tested. It never removes or
rewrites an entry, so human-authored definitions, translations and a curated status are safe; a
phrase that matches a term's deprecated synonym in its own context is suppressed rather than
re-added, and comes back in result.suppressed_alias_uses for violation reporting. New terms are
harvested, record at most three distinct sites, and are dated by an injectable clock that
defaults to today in UTC — so the same run merged twice leaves the file byte-identical.
Metadata
Release files for narrativetrace-glossary 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| narrativetrace_glossary-0.1.0.tar.gz | 80.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| narrativetrace_glossary-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 139.0 kB
Release files / narrativetrace_glossary-0.1.0.tar.gz
| Download URL | narrativetrace_glossary-0.1.0.tar.gz |
|---|---|
| Size | 80.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
5e4b7ecc1601a1133d181f824cc23fefae0cb7f80516a0354b77b95778a44b56
|
|
BLAKE2b-256 checksum How to use checksums |
041345fa4a613fa6355db5ef35bed776fee8c1f3efea2bd8d3e77b8be0303134
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.7 {"installer":{"name":"uv","version":"0.12.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / narrativetrace_glossary-0.1.0-py3-none-any.whl
| Download URL | narrativetrace_glossary-0.1.0-py3-none-any.whl |
|---|---|
| Size | 58.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
3b1d628777d92d4a289daeb730449e3792492f61749f193d6aabf0408d824bcf
|
|
BLAKE2b-256 checksum How to use checksums |
926ee45d0e8d6c62cde8ca4570271a6027090aaf3f2c557c8e1a59f6045a284b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.7 {"installer":{"name":"uv","version":"0.12.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|