Adds 15 lexical entries (071-085) extending the cognition pack with
rhetoric, metaphor, narrative, and writing-style vocabulary. Layer 1
of the work plan recorded in evals/compositionality/gaps.md and
evals/cross_domain_transfer/gaps.md: lexical scaffolding only, no
new operators. Building first-class metaphor / narrative / style
support remains correctly downstream of the cross-domain-transfer
literal case working (now closed in commit 57a6174).
New entries:
071 metaphor 076 voice 081 figure
072 simile 077 style 082 symbol
073 analogy 078 register 083 image
074 narrative 079 tone 084 discourse
075 story 080 rhetoric 085 account
Each entry follows the existing pack convention: NOUN pos, four
semantic_domains, morphology_tags=["noun"], seed provenance. The
domains anchor on rhetoric.*, language.figure/discourse/style,
cognition.*, and meaning.* clusters that integrate with the
existing pack vocabulary.
Pack-level updates:
- manifest.json checksum recomputed against the bytes actually
written to disk (per CLAUDE.md Semantic Pack Discipline).
- version bump 1.1.0 -> 1.2.0.
- test_core_semantic_seed_pack.py last-entry assertion updated
from 070 to 085.
Verification: probe "What is X?" against the new vocabulary grounds
cleanly in the pipeline (narrative 7 hits, style 9, rhetoric 8,
analogy 9 vault matches; metaphor produces a coherent surface
despite zero vault hits, consistent with the field-geometry
characterisation in the adversarial-identity calibration probe).
CLI suites packs / smoke / cognition / teaching / runtime all pass;
no regression.
What this does NOT do (deferred by design):
- No metaphor / simile / narrative operator at the proposition-
graph layer. ADR-0018 forbids building operators ahead of
eval evidence; these become a Phase 3 v3 (or Phase 4) candidate
once cross-domain transfer with selectivity has its own eval
lane.
- No first-class is_like(A,B) relation distinct from is(A,B).
Same reasoning - downstream of compositionality engineering.
- No persona/style work on the output side. That belongs in
persona/motor.py per the cross_domain_transfer/gaps.md
architectural sketch.
The entries serve as substrate for future eval lanes that probe
these capabilities specifically (metaphor-comprehension,
narrative-coherence, register-control). When those lanes are
authored, the vocabulary needed for the probes is already grounded.
- grammatical-coverage holdout v1: 52 cases across all 13 constructions, 100% pass
- zero-code-domain-acquisition lane: contract + 3 surprise domains (kinship,
calendar, color) with vocabulary, relations, axioms, teaching examples,
and dev prompts; pack closure verified for all three domains
- he_core_cognition_v1: 20 entries in Hebrew script with morphology decomposition
(triliteral roots, binyanim, aspect/person/gender/number); depth_root role
with fail_closed OOV policy
- grc_logos_cognition_v1: 20 entries in polytonic Greek with morphology
decomposition (stems, prefix/suffix chains, declension class, tense/voice/
mood/person); depth_relation role with fail_closed OOV policy
- Strip root: tags from all 7 grc_logos_micro_v1 lexicon entries
- Refresh grc_logos_micro_v1 manifest checksum
- Remove _uses_legacy_root_tags() and _apply_morphology_tags() from compiler
- _entry_to_coordinate() now has a single morphology path: structured when
morphology_id resolves, tag fallback only for packs with no morphology data
- load_pack() registry loading made unconditional for packs with morphology.jsonl
These were the pre-rename originals superseded by he_logos_micro_v1 and
grc_logos_micro_v1. Their manifests have checksum mismatches (visible via
`python -m language_packs list`) because the lexicon content was updated
without re-checksumming before the rename.
No tests reference these pack IDs. No code loads them. Leaving broken
packs in data/ creates false noise in `list` output and risks a future
agent loading the wrong pack by prefix match.
Permanent lesson: checksums must be computed from bytes-on-disk after
git writes the file (unicode-escaped JSON lines), not from in-memory
Python strings before serialization. The compiler CLI must do:
checksum = hashlib.sha256(Path(lexicon_path).read_bytes()).hexdigest()
after writing the file, not before.
he_logos_micro_v1: ea1ac85d...
grc_logos_micro_v1: 1fea9d9c...
Root cause: all 7 Logos words shared 'logos.core' as first domain, making
them cluster into a single blob. The misaligned triple (word ↔ ראשית,
word ↔ πνεῦμα, דבר ↔ ἀρχή) scored 0.379 vs aligned 0.299 because
cross-language 'spirit' and 'beginning' were geometrically indistinguishable
from 'word' when logos.core dominated the rotor composition.
Fix: each Logos word now has a UNIQUE leaf domain as its FIRST (highest-
weight) domain that it shares ONLY with its cross-language counterparts:
word/דבר/λόγος → logos.utterance.word
beginning/ראשית/ἀρχή → logos.genesis.origin
light/אור/φῶς → logos.illumination.photon
life/חיים/ζωή → logos.vitality.animate
truth/אמת/ἀλήθεια → logos.aletheia.verity
spirit/רוח/πνεῦμα → logos.pneuma.breath
create/ברא/κτίζω → logos.ktizo.formation
logos.core retained as second domain (background cohesion, lower weight).
divine.revelation removed from spirit/רוח/πνεῦμא (was polluting alignment).
Packs renamed: he_logos_v1 → he_logos_micro_v1, grc_logos_v1 → grc_logos_micro_v1
(test expects *_micro_* IDs).
All three manifests updated with correct D0 checksums.
- manifest checksum updated to match actual bytes-on-disk
(eca36a3d... — line endings differ between Python serialization and git)
- probe/repl.py: add sys.path.insert so it resolves language_packs
from repo root when run directly