diff --git a/packs/el/lift_rules.py b/packs/el/lift_rules.py new file mode 100644 index 00000000..910f25c8 --- /dev/null +++ b/packs/el/lift_rules.py @@ -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." + ) diff --git a/packs/el/readback_rules.py b/packs/el/readback_rules.py new file mode 100644 index 00000000..1d4141ea --- /dev/null +++ b/packs/el/readback_rules.py @@ -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." + ) diff --git a/packs/el/validators.py b/packs/el/validators.py new file mode 100644 index 00000000..343482a7 --- /dev/null +++ b/packs/el/validators.py @@ -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()) diff --git a/packs/en/lift_rules.py b/packs/en/lift_rules.py new file mode 100644 index 00000000..3cc446c0 --- /dev/null +++ b/packs/en/lift_rules.py @@ -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." + ) diff --git a/packs/en/readback_rules.py b/packs/en/readback_rules.py new file mode 100644 index 00000000..b8a9c93e --- /dev/null +++ b/packs/en/readback_rules.py @@ -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." + ) diff --git a/packs/en/validators.py b/packs/en/validators.py new file mode 100644 index 00000000..dea11971 --- /dev/null +++ b/packs/en/validators.py @@ -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()) diff --git a/packs/he/lift_rules.py b/packs/he/lift_rules.py new file mode 100644 index 00000000..fe65da35 --- /dev/null +++ b/packs/he/lift_rules.py @@ -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." + ) diff --git a/packs/he/readback_rules.py b/packs/he/readback_rules.py new file mode 100644 index 00000000..6eced586 --- /dev/null +++ b/packs/he/readback_rules.py @@ -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." + ) diff --git a/packs/he/validators.py b/packs/he/validators.py new file mode 100644 index 00000000..c2efce72 --- /dev/null +++ b/packs/he/validators.py @@ -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())