batch 5: en/he/el runtime boundaries — lift, readback, validators
This commit is contained in:
parent
8259e9a647
commit
dd3d5a396f
9 changed files with 534 additions and 0 deletions
42
packs/el/lift_rules.py
Normal file
42
packs/el/lift_rules.py
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
"""
|
||||
Lift rules for the Koine Greek depth pack.
|
||||
|
||||
Responsibility: receive a LinguisticAnalysis from the el pack analyzer
|
||||
and return a CandidatePressureBatch.
|
||||
|
||||
Koine Greek-specific lift requirements:
|
||||
- Tense-aspect: Greek tense encodes both time and aspect. The imperfect
|
||||
of eimi (en) lifts into existence.state.continuous, not existence.state.
|
||||
The aorist would lift into existence.event. These are not interchangeable.
|
||||
- Article system: the presence or absence of the article on a predicate
|
||||
nominative is semantically load-bearing (Colwell construction).
|
||||
Anarthrous predicate nominatives must lift with a qualitative tag.
|
||||
- Voice: middle voice is not passive. Middle voice lifts carry a
|
||||
reflexive or self-involving semantic that must be preserved.
|
||||
- Pros with accusative: lifts into relation.presence-toward,
|
||||
not relation.accompaniment. The preposition selects the sense.
|
||||
|
||||
Current status:
|
||||
Blocked on LinguisticAnalysis contract (el pack specific: must carry
|
||||
full tense-aspect-voice-mood bundle and article resolution).
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from core_ingest.pressure import CandidateGeometricPressure
|
||||
|
||||
|
||||
def lift(analysis: object) -> list["CandidateGeometricPressure"]:
|
||||
"""
|
||||
Lift a Greek LinguisticAnalysis into CandidateGeometricPressure packets.
|
||||
|
||||
Blocked on: el pack LinguisticAnalysis contract — must carry
|
||||
tense-aspect-voice-mood bundle and article resolution (arthrous/anarthrous)
|
||||
before this can be implemented correctly.
|
||||
"""
|
||||
raise NotImplementedError(
|
||||
"el:lift — LinguisticAnalysis contract for Koine Greek not yet finalized. "
|
||||
"Must carry tense, aspect, voice, mood, and article resolution."
|
||||
)
|
||||
37
packs/el/readback_rules.py
Normal file
37
packs/el/readback_rules.py
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
"""
|
||||
Readback rules for the Koine Greek depth pack.
|
||||
|
||||
Koine Greek readback produces grammatical Biblical Greek surface realizations.
|
||||
This is a depth-pack operation invoked only when the model targets Greek articulation.
|
||||
|
||||
Koine Greek-specific readback requirements:
|
||||
- Full inflection: case, number, gender on nouns/adjectives/articles;
|
||||
tense, voice, mood, person, number on verbs. Every word fully inflected.
|
||||
- Accent placement: Greek accents must be placed correctly.
|
||||
Unaccented output is not a valid surface realization.
|
||||
- Article resolution: the article must be present or absent based on
|
||||
the semantic role of the noun in the clause. Anarthrous predicates
|
||||
in copular constructions must remain anarthrous (Colwell).
|
||||
- Aspect selection: aorist vs. imperfect vs. perfect is not stylistic.
|
||||
Each carries distinct semantic content that must be honored.
|
||||
|
||||
Current status:
|
||||
Blocked on FieldState and SurfaceRealization types.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
|
||||
def readback(field_state: object, intent: object = None) -> object:
|
||||
"""
|
||||
Produce a grammatical Koine Greek surface realization from a field state.
|
||||
|
||||
Blocked on: FieldState and SurfaceRealization types.
|
||||
When implemented: must produce fully inflected and accented Greek output
|
||||
with correct article placement and tense-aspect selection.
|
||||
"""
|
||||
raise NotImplementedError(
|
||||
"el:readback — FieldState and SurfaceRealization types not yet "
|
||||
"finalized. When implemented: output must be fully inflected Koine Greek "
|
||||
"with correct accent placement, article resolution, and aspect selection."
|
||||
)
|
||||
92
packs/el/validators.py
Normal file
92
packs/el/validators.py
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
"""
|
||||
Validators for the Koine Greek depth pack.
|
||||
Same gate structure as en and he. Greek-specific gate notes inline.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
PACK_DIR = Path(__file__).parent
|
||||
|
||||
|
||||
def _gate_schema() -> tuple[bool, str]:
|
||||
return False, "not yet wired"
|
||||
|
||||
|
||||
def _gate_lexical() -> tuple[bool, str]:
|
||||
seen = set()
|
||||
for line in (PACK_DIR / "lemmas.jsonl").read_text(encoding="utf-8").splitlines():
|
||||
if not line.strip():
|
||||
continue
|
||||
record = json.loads(line)
|
||||
lid = record["lemma_id"]
|
||||
if lid in seen:
|
||||
return False, f"duplicate lemma_id: {lid}"
|
||||
seen.add(lid)
|
||||
return True, "ok"
|
||||
|
||||
|
||||
def _gate_morphology() -> tuple[bool, str]:
|
||||
known = set()
|
||||
for line in (PACK_DIR / "lemmas.jsonl").read_text(encoding="utf-8").splitlines():
|
||||
if line.strip():
|
||||
known.add(json.loads(line)["lemma_id"])
|
||||
for line in (PACK_DIR / "morphology.jsonl").read_text(encoding="utf-8").splitlines():
|
||||
if not line.strip():
|
||||
continue
|
||||
record = json.loads(line)
|
||||
if record["lemma_id"] not in known:
|
||||
return False, f"unknown lemma_id in morphology: {record['lemma_id']}"
|
||||
return True, "ok"
|
||||
|
||||
|
||||
def _gate_lift() -> tuple[bool, str]:
|
||||
# Greek lift requires tense-aspect-voice-mood and article resolution in analysis.
|
||||
return False, "el:lift() not yet implemented — requires tense/aspect/voice/mood/article in LinguisticAnalysis"
|
||||
|
||||
|
||||
def _gate_readback() -> tuple[bool, str]:
|
||||
return False, "el:readback() not yet implemented — must produce fully inflected and accented Greek"
|
||||
|
||||
|
||||
def _gate_determinism() -> tuple[bool, str]:
|
||||
return False, "depends on lift and readback"
|
||||
|
||||
|
||||
def _gate_alignment() -> tuple[bool, str]:
|
||||
return False, "anchors() not yet implemented"
|
||||
|
||||
|
||||
def _gate_coverage() -> tuple[bool, str]:
|
||||
return False, "depends on lift and readback gates"
|
||||
|
||||
|
||||
GATES = [
|
||||
("schema", _gate_schema),
|
||||
("lexical", _gate_lexical),
|
||||
("morphology", _gate_morphology),
|
||||
("lift", _gate_lift),
|
||||
("readback", _gate_readback),
|
||||
("determinism", _gate_determinism),
|
||||
("alignment", _gate_alignment),
|
||||
("coverage", _gate_coverage),
|
||||
]
|
||||
|
||||
|
||||
def validate_pack() -> dict:
|
||||
report = {"pack_id": "el", "active": False, "gates": {}}
|
||||
for name, gate_fn in GATES:
|
||||
passed, reason = gate_fn()
|
||||
report["gates"][name] = {"passed": passed, "reason": reason}
|
||||
if not passed:
|
||||
for remaining_name, _ in GATES[GATES.index((name, gate_fn)) + 1:]:
|
||||
report["gates"][remaining_name] = {"passed": False, "reason": "blocked by prior gate failure"}
|
||||
return report
|
||||
report["active"] = True
|
||||
return report
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import pprint
|
||||
pprint.pprint(validate_pack())
|
||||
45
packs/en/lift_rules.py
Normal file
45
packs/en/lift_rules.py
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
"""
|
||||
Lift rules for the English base pack.
|
||||
|
||||
Responsibility: receive a LinguisticAnalysis produced by the en pack normalizer
|
||||
and analyzer, and return a CandidatePressureBatch — a list of
|
||||
CandidateGeometricPressure packets ready for the IngestCompiler.
|
||||
|
||||
Design constraints:
|
||||
- Deterministic: identical input always produces identical output.
|
||||
- Lemma-first: lift targets are resolved through lemma_id → sense_id,
|
||||
not through surface-form heuristics.
|
||||
- Shared field target: every field_target must be a recognized CORE
|
||||
field primitive. No private semantic space.
|
||||
- This file must not import or invoke any external model or API.
|
||||
Lift is a deterministic, structure-driven operation.
|
||||
|
||||
Current status:
|
||||
The normalize() and analyze() interfaces are not yet fully specified
|
||||
for the en pack. Lift is blocked until those contracts are finalized
|
||||
and the LinguisticAnalysis type is stable.
|
||||
|
||||
Raise NotImplementedError at the exact boundary that is not yet designed
|
||||
rather than producing silent or approximate output.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from core_ingest.pressure import CandidateGeometricPressure
|
||||
|
||||
|
||||
def lift(analysis: object) -> list["CandidateGeometricPressure"]:
|
||||
"""
|
||||
Lift a LinguisticAnalysis from the en pack into a list of
|
||||
CandidateGeometricPressure packets.
|
||||
|
||||
Blocked on: finalization of the LinguisticAnalysis contract
|
||||
and the CandidateGeometricPressure construction interface.
|
||||
"""
|
||||
raise NotImplementedError(
|
||||
"en:lift — LinguisticAnalysis contract not yet finalized. "
|
||||
"Implement after analyze() and CandidateGeometricPressure "
|
||||
"construction interface are locked."
|
||||
)
|
||||
37
packs/en/readback_rules.py
Normal file
37
packs/en/readback_rules.py
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
"""
|
||||
Readback rules for the English base pack.
|
||||
|
||||
Responsibility: receive a resolved field state (or a field state fragment
|
||||
with a stated communicative intent) and produce a grammatical English
|
||||
surface realization.
|
||||
|
||||
Design constraints:
|
||||
- Readback is pack-local. This file does not reach into he or el rules.
|
||||
- Grammatical agreement is fully handled here: number, tense, mood.
|
||||
- Ambiguity resolution is deterministic: when multiple lemmas could
|
||||
express the same field target, rank and constraint matching decide.
|
||||
- This file must not invoke any external model or API.
|
||||
|
||||
Current status:
|
||||
Readback requires the FieldState type and the SurfaceRealization
|
||||
return type to be stable. Both are blocked on the field primitive
|
||||
specification work in the core field layer.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
pass
|
||||
|
||||
|
||||
def readback(field_state: object, intent: object = None) -> object:
|
||||
"""
|
||||
Produce a grammatical English surface realization from a field state.
|
||||
|
||||
Blocked on: FieldState type and SurfaceRealization interface.
|
||||
"""
|
||||
raise NotImplementedError(
|
||||
"en:readback — FieldState and SurfaceRealization types not yet "
|
||||
"finalized. Implement after the core field primitive layer is locked."
|
||||
)
|
||||
108
packs/en/validators.py
Normal file
108
packs/en/validators.py
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
"""
|
||||
Validators for the English base pack.
|
||||
|
||||
Runs all eight gates in sequence and returns a ValidationReport.
|
||||
A gate failure halts further validation — the pack is not partially active.
|
||||
|
||||
Gate status reflects current implementation reality.
|
||||
Do not mark a gate True until it passes programmatically.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
PACK_DIR = Path(__file__).parent
|
||||
|
||||
|
||||
def _gate_schema() -> tuple[bool, str]:
|
||||
"""Validate all .jsonl files against their JSON Schema counterparts."""
|
||||
# Requires: jsonschema library and schema files under packs/common/schema/
|
||||
# Status: schema files exist; validation runner not yet wired.
|
||||
return False, "not yet wired"
|
||||
|
||||
|
||||
def _gate_lexical() -> tuple[bool, str]:
|
||||
"""Check lemma_id uniqueness and field_hook validity."""
|
||||
seen = set()
|
||||
for line in (PACK_DIR / "lemmas.jsonl").read_text(encoding="utf-8").splitlines():
|
||||
if not line.strip():
|
||||
continue
|
||||
record = json.loads(line)
|
||||
lid = record["lemma_id"]
|
||||
if lid in seen:
|
||||
return False, f"duplicate lemma_id: {lid}"
|
||||
seen.add(lid)
|
||||
return True, "ok"
|
||||
|
||||
|
||||
def _gate_morphology() -> tuple[bool, str]:
|
||||
"""Check all morphology records reference a known lemma_id."""
|
||||
known = set()
|
||||
for line in (PACK_DIR / "lemmas.jsonl").read_text(encoding="utf-8").splitlines():
|
||||
if line.strip():
|
||||
known.add(json.loads(line)["lemma_id"])
|
||||
for line in (PACK_DIR / "morphology.jsonl").read_text(encoding="utf-8").splitlines():
|
||||
if not line.strip():
|
||||
continue
|
||||
record = json.loads(line)
|
||||
if record["lemma_id"] not in known:
|
||||
return False, f"unknown lemma_id in morphology: {record['lemma_id']}"
|
||||
return True, "ok"
|
||||
|
||||
|
||||
def _gate_lift() -> tuple[bool, str]:
|
||||
"""Run lift probes. Blocked on lift() implementation."""
|
||||
return False, "lift() not yet implemented"
|
||||
|
||||
|
||||
def _gate_readback() -> tuple[bool, str]:
|
||||
"""Run readback probes. Blocked on readback() implementation."""
|
||||
return False, "readback() not yet implemented"
|
||||
|
||||
|
||||
def _gate_determinism() -> tuple[bool, str]:
|
||||
"""Verify normalize() and lift() are deterministic. Blocked on both."""
|
||||
return False, "normalize() and lift() not yet implemented"
|
||||
|
||||
|
||||
def _gate_alignment() -> tuple[bool, str]:
|
||||
"""Check anchors() returns the required trilingual anchor set."""
|
||||
return False, "anchors() not yet implemented"
|
||||
|
||||
|
||||
def _gate_coverage() -> tuple[bool, str]:
|
||||
"""Run all probes in probes/. Blocked on lift and readback."""
|
||||
return False, "depends on lift and readback gates"
|
||||
|
||||
|
||||
GATES = [
|
||||
("schema", _gate_schema),
|
||||
("lexical", _gate_lexical),
|
||||
("morphology", _gate_morphology),
|
||||
("lift", _gate_lift),
|
||||
("readback", _gate_readback),
|
||||
("determinism", _gate_determinism),
|
||||
("alignment", _gate_alignment),
|
||||
("coverage", _gate_coverage),
|
||||
]
|
||||
|
||||
|
||||
def validate_pack() -> dict:
|
||||
"""Run all eight gates. Returns a report with pass/fail and reason per gate."""
|
||||
report = {"pack_id": "en", "active": False, "gates": {}}
|
||||
for name, gate_fn in GATES:
|
||||
passed, reason = gate_fn()
|
||||
report["gates"][name] = {"passed": passed, "reason": reason}
|
||||
if not passed:
|
||||
# Gate failure halts further validation.
|
||||
for remaining_name, _ in GATES[GATES.index((name, gate_fn)) + 1:]:
|
||||
report["gates"][remaining_name] = {"passed": False, "reason": "blocked by prior gate failure"}
|
||||
return report
|
||||
report["active"] = True
|
||||
return report
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import pprint
|
||||
pprint.pprint(validate_pack())
|
||||
42
packs/he/lift_rules.py
Normal file
42
packs/he/lift_rules.py
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
"""
|
||||
Lift rules for the Hebrew depth pack.
|
||||
|
||||
Responsibility: receive a LinguisticAnalysis from the he pack analyzer
|
||||
and return a CandidatePressureBatch.
|
||||
|
||||
Hebrew-specific lift requirements:
|
||||
- Binyan (verb stem) must be resolved before field_target is selected.
|
||||
The same root in qal vs. hiphil may lift into different field targets.
|
||||
- Aspect (qatal/yiqtol/wayyiqtol) contributes to the pressure kind
|
||||
and temporal annotation of the candidate.
|
||||
- Construct chains must be handled as relational frames: the head
|
||||
lemma and the genitive together determine the lift target.
|
||||
- The implicit copula: when haya is absent, the copular frame is
|
||||
inferred from syntactic position, not from a present verb form.
|
||||
- bara in qal: always lifts into creation.act.ex-nihilo.
|
||||
The divine-agent constraint must be verified before this lift.
|
||||
|
||||
Current status:
|
||||
Blocked on LinguisticAnalysis contract (he pack specific: must carry
|
||||
binyan, aspect, and construct-chain annotations).
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from core_ingest.pressure import CandidateGeometricPressure
|
||||
|
||||
|
||||
def lift(analysis: object) -> list["CandidateGeometricPressure"]:
|
||||
"""
|
||||
Lift a Hebrew LinguisticAnalysis into CandidateGeometricPressure packets.
|
||||
|
||||
Blocked on: he pack LinguisticAnalysis contract — must carry
|
||||
binyan, aspect, and construct-chain annotations before this
|
||||
can be implemented correctly.
|
||||
"""
|
||||
raise NotImplementedError(
|
||||
"he:lift — LinguisticAnalysis contract for Hebrew not yet finalized. "
|
||||
"Must carry binyan, aspect, and construct-chain annotations."
|
||||
)
|
||||
38
packs/he/readback_rules.py
Normal file
38
packs/he/readback_rules.py
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
"""
|
||||
Readback rules for the Hebrew depth pack.
|
||||
|
||||
Hebrew readback produces grammatical Biblical Hebrew surface realizations
|
||||
from field state. This is a depth-pack operation: it is not invoked
|
||||
by default, only when the model explicitly targets Hebrew articulation.
|
||||
|
||||
Hebrew-specific readback requirements:
|
||||
- Verb selection must respect binyan: the field target and agent
|
||||
semantics together determine which binyan is appropriate.
|
||||
- Aspect selection is not optional: qatal, yiqtol, and wayyiqtol
|
||||
carry distinct temporal and narrative semantics.
|
||||
- Nikud (vowel points) must be produced, not left unpointed.
|
||||
Unpointed output is not a valid surface realization for this pack.
|
||||
- Construct chains must be assembled correctly: head in construct
|
||||
state, genitive following, no article on the construct head.
|
||||
- The implicit copula must be handled: in nominal clauses, haya
|
||||
is omitted in the present tense unless emphasis requires it.
|
||||
|
||||
Current status:
|
||||
Blocked on FieldState and SurfaceRealization types.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
|
||||
def readback(field_state: object, intent: object = None) -> object:
|
||||
"""
|
||||
Produce a grammatical Hebrew surface realization from a field state.
|
||||
|
||||
Blocked on: FieldState and SurfaceRealization types.
|
||||
When implemented: must produce fully pointed (nikud) Hebrew output.
|
||||
"""
|
||||
raise NotImplementedError(
|
||||
"he:readback — FieldState and SurfaceRealization types not yet "
|
||||
"finalized. When implemented: output must be fully pointed Hebrew "
|
||||
"with correct binyan, aspect, and construct-chain handling."
|
||||
)
|
||||
93
packs/he/validators.py
Normal file
93
packs/he/validators.py
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
"""
|
||||
Validators for the Hebrew depth pack.
|
||||
Same gate structure as the en pack. Hebrew-specific gate notes inline.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
PACK_DIR = Path(__file__).parent
|
||||
|
||||
|
||||
def _gate_schema() -> tuple[bool, str]:
|
||||
return False, "not yet wired"
|
||||
|
||||
|
||||
def _gate_lexical() -> tuple[bool, str]:
|
||||
seen = set()
|
||||
for line in (PACK_DIR / "lemmas.jsonl").read_text(encoding="utf-8").splitlines():
|
||||
if not line.strip():
|
||||
continue
|
||||
record = json.loads(line)
|
||||
lid = record["lemma_id"]
|
||||
if lid in seen:
|
||||
return False, f"duplicate lemma_id: {lid}"
|
||||
seen.add(lid)
|
||||
return True, "ok"
|
||||
|
||||
|
||||
def _gate_morphology() -> tuple[bool, str]:
|
||||
known = set()
|
||||
for line in (PACK_DIR / "lemmas.jsonl").read_text(encoding="utf-8").splitlines():
|
||||
if line.strip():
|
||||
known.add(json.loads(line)["lemma_id"])
|
||||
for line in (PACK_DIR / "morphology.jsonl").read_text(encoding="utf-8").splitlines():
|
||||
if not line.strip():
|
||||
continue
|
||||
record = json.loads(line)
|
||||
if record["lemma_id"] not in known:
|
||||
return False, f"unknown lemma_id in morphology: {record['lemma_id']}"
|
||||
return True, "ok"
|
||||
|
||||
|
||||
def _gate_lift() -> tuple[bool, str]:
|
||||
# Hebrew lift additionally requires binyan and aspect annotations
|
||||
# in the LinguisticAnalysis. These are not yet specified.
|
||||
return False, "he:lift() not yet implemented — requires binyan/aspect in LinguisticAnalysis"
|
||||
|
||||
|
||||
def _gate_readback() -> tuple[bool, str]:
|
||||
return False, "he:readback() not yet implemented — must produce pointed Hebrew output"
|
||||
|
||||
|
||||
def _gate_determinism() -> tuple[bool, str]:
|
||||
return False, "depends on lift and readback"
|
||||
|
||||
|
||||
def _gate_alignment() -> tuple[bool, str]:
|
||||
return False, "anchors() not yet implemented"
|
||||
|
||||
|
||||
def _gate_coverage() -> tuple[bool, str]:
|
||||
return False, "depends on lift and readback gates"
|
||||
|
||||
|
||||
GATES = [
|
||||
("schema", _gate_schema),
|
||||
("lexical", _gate_lexical),
|
||||
("morphology", _gate_morphology),
|
||||
("lift", _gate_lift),
|
||||
("readback", _gate_readback),
|
||||
("determinism", _gate_determinism),
|
||||
("alignment", _gate_alignment),
|
||||
("coverage", _gate_coverage),
|
||||
]
|
||||
|
||||
|
||||
def validate_pack() -> dict:
|
||||
report = {"pack_id": "he", "active": False, "gates": {}}
|
||||
for name, gate_fn in GATES:
|
||||
passed, reason = gate_fn()
|
||||
report["gates"][name] = {"passed": passed, "reason": reason}
|
||||
if not passed:
|
||||
for remaining_name, _ in GATES[GATES.index((name, gate_fn)) + 1:]:
|
||||
report["gates"][remaining_name] = {"passed": False, "reason": "blocked by prior gate failure"}
|
||||
return report
|
||||
report["active"] = True
|
||||
return report
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import pprint
|
||||
pprint.pprint(validate_pack())
|
||||
Loading…
Reference in a new issue