diff --git a/.github/workflows/english-gonol.yml b/.github/workflows/english-gonol.yml index 2335b2ed..fef39888 100644 --- a/.github/workflows/english-gonol.yml +++ b/.github/workflows/english-gonol.yml @@ -21,6 +21,10 @@ jobs: env: UCNS_SOURCE_ROOT: ${{ github.workspace }}/_deps/ucns-motion ENGLISH_GONOL_UCNS_ROOT: ${{ github.workspace }}/_deps/ucns-relational + OEWN_SOURCE_ROOT: ${{ github.workspace }}/_deps/oewn/src/yaml + EDCM_METRIC_ORIGIN_ROOT: ${{ github.workspace }}/_deps/edcm-metric-origin + ENGLISH_GONOL_FULL_CONSTRUCT_ROOT: ${{ github.workspace }}/_state/english-full-construct + REQUIRE_METRIC_ORIGIN_SOURCES: "1" steps: - name: Checkout stack uses: actions/checkout@v7.0.1 @@ -45,19 +49,71 @@ jobs: path: _deps/ucns-relational persist-credentials: false + - name: Checkout pinned OEWN 2025 source + uses: actions/checkout@v7.0.1 + with: + repository: globalwordnet/english-wordnet + ref: dc343f2683279ecbb13fab4e2fd778d7b162d287 + path: _deps/oewn + persist-credentials: false + + - name: Checkout pinned EDCM metric-origin producer + uses: actions/checkout@v7.0.1 + with: + repository: The-Interdependency/edcm + ref: ce645e4b3cce0308676837f60bed118fa74f23ac + path: _deps/edcm-metric-origin + persist-credentials: false + + - name: Checkout pinned full-construct carrier + uses: actions/checkout@v7.0.1 + with: + repository: The-Interdependency/ucns + ref: 4f863ad37096b7baab8f62820ad5cb937b62a3a7 + path: _deps/ucns-carrier + persist-credentials: false + - name: Set up Python uses: actions/setup-python@v7.0.0 with: python-version: "3.12" - - name: Install pytest - run: python -m pip install --disable-pip-version-check pytest + - name: Install construction prerequisites + run: python -m pip install --disable-pip-version-check pytest PyYAML - - name: Verify pinned UCNS source identities + - name: Verify all pinned source identities run: | test "$(git -C _deps/ucns-motion rev-parse HEAD)" = "5a042416ef62abd9b674523284c2a31193918d66" test "$(git -C _deps/ucns-relational rev-parse HEAD)" = "d7c6f51304ed6c32d48badf63132bea6de8af497" + test "$(git -C _deps/oewn rev-parse HEAD)" = "dc343f2683279ecbb13fab4e2fd778d7b162d287" + test "$(git -C _deps/edcm-metric-origin rev-parse HEAD)" = "ce645e4b3cce0308676837f60bed118fa74f23ac" + test "$(git -C _deps/ucns-carrier rev-parse HEAD)" = "4f863ad37096b7baab8f62820ad5cb937b62a3a7" + + - name: Preflight full-corpus resources + run: | + python - <<'PY' + import os, shutil + assert shutil.disk_usage(os.environ["RUNNER_TEMP"]).free >= 8 * 1024**3 + assert os.sysconf("SC_PHYS_PAGES") * os.sysconf("SC_PAGE_SIZE") >= 5 * 1024**3 + PY + + - name: Build complete pinned corpus for metric-origin replay + working-directory: research/english-gonol + run: | + python -m english_gonol.full_construct_run \ + --source-root "$OEWN_SOURCE_ROOT" \ + --ucns-source-root "$GITHUB_WORKSPACE/_deps/ucns-carrier" \ + --out-dir "$ENGLISH_GONOL_FULL_CONSTRUCT_ROOT" - name: English Gonol construction tests working-directory: research/english-gonol run: python -m pytest -q tests + + - name: Retain full-corpus metric-origin evidence + uses: actions/upload-artifact@v7.0.1 + with: + name: metric-origin-replay + path: | + ${{ env.ENGLISH_GONOL_FULL_CONSTRUCT_ROOT }}/manifest.json + ${{ env.ENGLISH_GONOL_FULL_CONSTRUCT_ROOT }}/metric-origin-replay.json + if-no-files-found: error diff --git a/STACK_MANIFEST.md b/STACK_MANIFEST.md index 40fbd92b..3ee6ff36 100644 --- a/STACK_MANIFEST.md +++ b/STACK_MANIFEST.md @@ -17,7 +17,7 @@ Provenance and authority-boundary record for `The-Interdependency/stack`. - English four-view complete-corpus audit UTC: `2026-09-22`, exact view source `1f9a35eb355296fc88d09784c7a3e2e95511ca31`; all 164,864 words, native and independent agreement. - Stack-manifest schema: `the-interdependency.stack-manifest` version `1.1.0` - Work-graph digest (SHA-256 over canonical `repositories` + `research_participants` + `boundaries` JSON): - `7384687cde8e9d18a1019fecd62adbaa6278930bb556546db05062ef4a348f0b` + `f0ce9606681cc053d9dcbb010805a932290207d49a5d8714297b8c3ce455ec41` - Weave workspace creation UTC: `2026-09-28`; new specification-first research starts from the intended multi-arity interleaving mechanism without URPCS inheritance - Machine-readable copy: [`stack-manifest.json`](stack-manifest.json) @@ -65,6 +65,7 @@ release identity. | `research/urpcs/` | `The-Interdependency/stack` | `a428a41a38a8b30bacb7025a4d54070b228a8089` | retired substituted-codec historical evidence only; no active URPCS authority or evidence transfer | no | | `research/weave/` | `The-Interdependency/stack` | `1ba201449731337dc20c564788f4303c8910bfdd` | full gonol/private-key/thread/corpus/interleave/asymmetric construction research; native derivation unresolved; no URPCS implementation inheritance or security standing | no | | `research/english-gonol/` | `The-Interdependency/stack` | `99b3598b02a6e683b3c84184d8ea443b12fc0e1a` | stack-local English lexical/gonol construction separated from EDCM; full pinned-corpus v2 build/replay survived; consumes UCNS geometry; EDCM may evaluate outputs but does not define construction | no | +| `research/english-gonol/` | `The-Interdependency/edcm` | `ce645e4b3cce0308676837f60bed118fa74f23ac` | exact EDCM semantic metric-origin producer; supplies metric definitions and proxy-alignment metadata without refreshing `libs/edcm` or transferring measurement authority | no | | `research/python-gonol/` | `The-Interdependency/stack` | `0e8384bbb60e4c2189016a212bdd0030d04aed7d` | stack-local bottom-up Python 3.12 source gonol construction; applies METAPAT affixiation semantics, consumes optional UCNS geometry, and transfers no language authority to UCNS or EDCM | no | | `research/ucns/` | `The-Interdependency/ucns` | `1975fe70cf4e0826a8020c2da3047569e277af64` | explicit source base for integrated stack-local UCNS research; does not refresh or replace the manifest-pinned `libs/ucns` canonical view | no | | `research/from-photons-to-macroverse/` | `The-Interdependency/stack` | `77ef8c7fb0ff75a524181655ee9f9641372768f7` | target composition forge baseline at audit start | no | diff --git a/research/english-gonol/BASE.json b/research/english-gonol/BASE.json index 33475775..cb814012 100644 --- a/research/english-gonol/BASE.json +++ b/research/english-gonol/BASE.json @@ -18,5 +18,11 @@ "protocol": "FULL_VIEW_AUDIT.json", "work_graph": "../../stack-manifest.json#research_participants[workspace=research/english-gonol/]", "authority_transfer": false + }, + "metric_origin_source": { + "repository": "The-Interdependency/edcm", + "commit": "ce645e4b3cce0308676837f60bed118fa74f23ac", + "relation": "exact EDCM semantic metric-origin producer; does not refresh the historical extraction source or libs/edcm pin", + "authority_transfer": false } } diff --git a/research/english-gonol/EDCM_METRIC_ORIGINS_SOURCE.json b/research/english-gonol/EDCM_METRIC_ORIGINS_SOURCE.json new file mode 100644 index 00000000..75f66b5b --- /dev/null +++ b/research/english-gonol/EDCM_METRIC_ORIGINS_SOURCE.json @@ -0,0 +1,186 @@ +{ + "schema": "edcm.metric-origin-spec-fixture", + "version": "0.3.0", + "producer_repository": "The-Interdependency/edcm", + "producer_commit": "ce645e4b3cce0308676837f60bed118fa74f23ac", + "specs": { + "C": { + "surface_terms": [ + "Constraint Strain" + ], + "semantic_definition": "constraint strain is pressure produced by contradiction within the measured window", + "standing": "resolved", + "measurement_alignment": "proxy", + "unresolved": [ + "implicit contradiction semantics are not measured by the maintained proxy" + ], + "construction_terms": [ + "constraint", + "strain", + "contradiction", + "pressure" + ] + }, + "R": { + "surface_terms": [ + "Refusal Density" + ], + "semantic_definition": "refusal density is the concentration of refusal relative to active constraint statements", + "standing": "resolved", + "measurement_alignment": "proxy", + "unresolved": [ + "implemented denominator is token-count scale, not counted constraint statements" + ], + "construction_terms": [ + "refusal", + "density", + "refusal", + "constraint" + ] + }, + "F": { + "surface_terms": [ + "Fixation" + ], + "semantic_definition": "fixation is persistence of substantially the same constraint-bearing pattern across successive states", + "standing": "resolved", + "measurement_alignment": "proxy", + "unresolved": [ + "maintained implementation is a lexical structural proxy, not embedding similarity" + ], + "construction_terms": [ + "fixation", + "persistence", + "repetition" + ] + }, + "E": { + "surface_terms": [ + "Escalation" + ], + "semantic_definition": "escalation is positive change in commitment or constraint intensity across sequence", + "standing": "resolved", + "measurement_alignment": "proxy", + "unresolved": [ + "maintained implementation does not directly compute commitment-intensity derivative" + ], + "construction_terms": [ + "escalation", + "increase", + "commitment", + "intensity" + ] + }, + "D": { + "surface_terms": [ + "Deflection" + ], + "semantic_definition": "deflection is movement away from the active constraint-bearing subject or relation", + "standing": "resolved", + "measurement_alignment": "proxy", + "unresolved": [ + "prior-round lexical overlap substitutes for active-constraint topic tracking" + ], + "construction_terms": [ + "deflection", + "movement", + "away", + "constraint" + ] + }, + "N": { + "surface_terms": [ + "Noise" + ], + "semantic_definition": "noise is activity that consumes representational space without proportionate constraint resolution", + "standing": "resolved", + "measurement_alignment": "proxy", + "unresolved": [ + "maintained implementation measures repetition and entropy rather than resolution ratio" + ], + "construction_terms": [ + "noise", + "repetition", + "without", + "resolution" + ] + }, + "I": { + "surface_terms": [ + "Integration Failure" + ], + "semantic_definition": "integration failure is failure of a correction or newly supplied constraint to alter subsequent behavior accordingly", + "standing": "resolved", + "measurement_alignment": "proxy", + "unresolved": [ + "maintained implementation does not observe subsequent integration behavior" + ], + "construction_terms": [ + "integration", + "failure", + "correction", + "change" + ] + }, + "O": { + "surface_terms": [ + "Overextension", + "Overconfidence" + ], + "semantic_definition": "O has conflicting maintained semantic names and therefore has no closed semantic origin yet", + "standing": "hmmm", + "measurement_alignment": "conflict", + "unresolved": [ + "marker canon says Overextension; compute.py says Overconfidence" + ], + "construction_terms": [] + }, + "L": { + "surface_terms": [ + "Load", + "Coherence Loss" + ], + "semantic_definition": "L has conflicting maintained semantic names and therefore has no closed semantic origin yet", + "standing": "hmmm", + "measurement_alignment": "conflict", + "unresolved": [ + "marker canon says Load; compute.py says Coherence Loss" + ], + "construction_terms": [] + }, + "P": { + "surface_terms": [ + "Progress" + ], + "semantic_definition": "progress is newly integrated information or state change that advances resolution relative to the prior state", + "standing": "resolved", + "measurement_alignment": "proxy", + "unresolved": [ + "progress is explicitly implemented as a proxy" + ], + "construction_terms": [ + "progress", + "novelty", + "change", + "resolution" + ] + }, + "kappa": { + "surface_terms": [ + "Stored Tension" + ], + "semantic_definition": "stored tension is unresolved dissonance carried forward as circuit state", + "standing": "resolved", + "measurement_alignment": "proxy", + "unresolved": [ + "resolution function is currently approximated from dissonance" + ], + "construction_terms": [ + "stored", + "tension", + "unresolved", + "conflict" + ] + } + } +} diff --git a/research/english-gonol/docs/metric-origin-space.md b/research/english-gonol/docs/metric-origin-space.md new file mode 100644 index 00000000..01eee09e --- /dev/null +++ b/research/english-gonol/docs/metric-origin-space.md @@ -0,0 +1,81 @@ +# EDCM metric-origin construction — usage guidance + +Stack consumes the merged EDCM producer +`ce645e4b3cce0308676837f60bed118fa74f23ac`. EDCM owns the metric meanings, +scalar computations, conflicts, and proxy limitations. Stack constructs their +declared ordered English terms. Construction closure does not establish +measurement validity. O and L remain unclosed `hmmm` records. + +`BASE.json`, the local metric work graph, the Stack manifests, the source fixture, +and CI register this same producer. The loader binds the fixture's complete bytes +to `FIXTURE_SHA256`; `fixture_path` accepts an exact copy, not alternate semantic +definitions or unregistered producer labels. Update the owning EDCM source first +and replay the cross-source check before changing this pin. + +## Reproduce the authoritative checks + +From `research/english-gonol`, install `pytest` and `PyYAML`. Use clean checkouts: + +| Input | Commit | Path passed to the checks | +|---|---|---| +| EDCM | `ce645e4b3cce0308676837f60bed118fa74f23ac` | checkout root | +| OEWN 2025 | `dc343f2683279ecbb13fab4e2fd778d7b162d287` | checkout `src/yaml` | +| UCNS full-construct carrier | `4f863ad37096b7baab8f62820ad5cb937b62a3a7` | checkout root | + +Set the three absolute paths for your checkouts and a new output directory: + +```bash +export OEWN_SOURCE_ROOT=/path/to/oewn/src/yaml +export EDCM_METRIC_ORIGIN_ROOT=/path/to/edcm +export ENGLISH_GONOL_FULL_CONSTRUCT_ROOT=/path/to/generated/english-full-construct +export REQUIRE_METRIC_ORIGIN_SOURCES=1 +python -m english_gonol.full_construct_run \ + --source-root "$OEWN_SOURCE_ROOT" \ + --ucns-source-root /path/to/ucns-carrier \ + --out-dir "$ENGLISH_GONOL_FULL_CONSTRUCT_ROOT" +python -m pytest -q tests/test_edcm_metric_origins.py +``` + +Preflight enough disk and memory before starting the full construction; CI +requires 8 GiB free disk and 5 GiB RAM. Let an admitted run finish naturally. +The complete workflow also sets the motion and relational UCNS source paths +needed by the rest of the English suite. + +The tests verify the actual EDCM checkout, compare all consumed semantic fields, +check exact term admission against the complete pinned corpus, replay the full +construct receipt, construct every metric origin, and bind the emitted records +through the exact merged EDCM adapter. Required missing sources fail instead of +skipping. `metric-origin-replay.json` contains all 11 origin records and a clearly +synthetic transcript measurement used only to test adapter compatibility. + +## Export for independent observations + +With the environment above, this writes an ordered JSON object ready for +EDCM's `build_semantic_metric_space`: + +```bash +python - <<'PY' +import json, os +from pathlib import Path +from english_gonol.edcm_metric_origins import ( + build_metric_origin_set, load_metric_origin_specs, +) +state = Path(os.environ["ENGLISH_GONOL_FULL_CONSTRUCT_ROOT"]) +records = {metric: build_metric_origin_set(state, metric).to_dict() + for metric in load_metric_origin_specs()["specs"]} +(state / "metric-origins.json").write_text(json.dumps(records, indent=2) + "\n") +PY +``` + +Load that JSON object in the pinned EDCM environment, build the space, and call +`bind_round_metrics` with maintained `RoundMetrics` and the separate observation's +evidence receipt. See EDCM's `docs/semantic-metric-space.md` for the runnable +measurement example and adapter input contract. Keep vector order; do not sort +the exported metric keys. + +## hmmm + +O conflicts between Overextension and Overconfidence; L conflicts between Load +and Coherence Loss. The observed-construct-to-origin projection remains +unestablished. Receipts establish content identity, not cryptographic producer +authentication, empirical validity, or canon selection. diff --git a/research/english-gonol/docs/work-graphs/metric-origin-space-v0.json b/research/english-gonol/docs/work-graphs/metric-origin-space-v0.json new file mode 100644 index 00000000..2af78b03 --- /dev/null +++ b/research/english-gonol/docs/work-graphs/metric-origin-space-v0.json @@ -0,0 +1,45 @@ +{ + "schema": "the-interdependency.stack-manifest", + "version": "1.0.0", + "work_graph_sha256": "1950c6601417665245f17c27d9f292b243194fdf7a0cec380d6a7acfc61f0bb6", + "repositories": [ + { + "repository": "The-Interdependency/edcm", + "commit": "ce645e4b3cce0308676837f60bed118fa74f23ac", + "authority": "metric definitions, scalar measurement, and evidence/readout contracts", + "relation": "defines source-owned construction terms and binds scalar readouts to Stack origin receipts" + }, + { + "repository": "The-Interdependency/stack", + "commit": "316a8c8f10e2dacd34007e076bcf20c4d1ecda00", + "authority": "current English Gonol semantic construction", + "relation": "constructs exact EDCM construction terms as verified O_W/O_G metric origin sets" + }, + { + "repository": "The-Interdependency/metapat", + "commit": "1cdfb09dd00a451cee30eec2e78624df8c682662", + "authority": "cross-domain semantic constraints", + "relation": "constrains semantic transfer; no metric validity transfer" + }, + { + "repository": "The-Interdependency/ucns", + "commit": "1975fe70cf4e0826a8020c2da3047569e277af64", + "authority": "gonol geometry consumed by Stack English construction", + "relation": "underlying geometry only; no metric semantics or measurement validity" + } + ], + "boundaries": { + "authority_transfer": false, + "proof_status_transfer": false, + "measurement_status_transfer": false, + "semantic_mapping": "declared mapping", + "agent_scope": "cross-repository-work-graph", + "hmmm": [ + "O semantic origin conflicts: Overextension versus Overconfidence", + "L semantic origin conflicts: Load versus Coherence Loss", + "lawful observed-construct to metric-origin projection/distance is unresolved", + "full-corpus closure requires the generated English construct database", + "originating operator decision lacks immutable public provenance; repository adoption is prospective" + ] + } +} diff --git a/research/english-gonol/english_gonol/edcm_metric_origins.py b/research/english-gonol/english_gonol/edcm_metric_origins.py new file mode 100644 index 00000000..572c5585 --- /dev/null +++ b/research/english-gonol/english_gonol/edcm_metric_origins.py @@ -0,0 +1,269 @@ +"""Construct EDCM metric descriptions as English hyperspace origin sets. + +Only EDCM-owned construction terms enter the semantic origin. Measurement rules +and observed evidence stay outside it. Resolved origins require the exact pinned +English v2 construct receipt; unresolved EDCM semantics remain unclosed hmmm. + +Usage guidance: see ``docs/metric-origin-space.md`` for source checkout, +complete-corpus construction, export, and EDCM adapter commands. +""" + +# === MODULE_BUILD === +# id: english_edcm_metric_origin_sets_v0 +# module_name: english_gonol.edcm_metric_origins +# module_kind: constructor +# summary: constructs ordered English hyperspace origin sets from EDCM-owned exact construction terms +# owner: Stack English Gonol Construction +# public_surface: MetricOriginSet, OriginComponent, load_metric_origin_specs, build_metric_origin_set +# internal_surface: verified construct identity, exact-run admission, deterministic receipt +# auth_boundary: none +# storage_boundary: read +# network_boundary: none +# user_data_boundary: none +# admin_only: false +# tests: research/english-gonol/tests/test_edcm_metric_origins.py +# rollout: stack-local research candidate +# rollback: remove module fixture and tests; EDCM source specs remain unchanged +# requires: english_gonol_language_hyperspace, english_gonol_full_construct, edcm metric-origin spec fixture +# since: 2026-10-03 +# unresolved: O and L source semantics conflict; lawful observed-state projection to these origins remains hmmm +# === END MODULE_BUILD === + +# === CONTRACTS === +# id: metric_origin_words_define_instrument_not_evidence +# given: an EDCM metric origin set is constructed +# then: it contains only source-owned semantic construction and no observation or metric value +# class: boundary_contract +# +# id: metric_origin_preserves_order_identity_provenance +# given: a resolved metric description is admitted by the verified English construct +# then: exact ordered word and whitespace-glyph axes plus producer and verified construct identities survive in the receipt +# class: correctness +# +# id: metric_origin_unresolved_fails_open_as_hmmm_not_closed +# given: the EDCM source spec is hmmm +# then: no semantic components are constructed and closed is false +# class: safety +# +# id: metric_origin_receipt_binds_schema +# given: any metric-origin record is emitted +# then: receipt identity covers schema version and every serialized field except the receipt itself +# class: identity_contract +# +# id: metric_origin_terms_admitted_by_pinned_corpus +# given: resolved EDCM construction terms are compared with the exact pinned OEWN 2025 source +# then: every term is an exact admitted word surface before an origin is licensed +# class: provenance_contract +# +# id: metric_origin_source_fixture_matches_pinned_edcm +# given: the Stack source fixture and exact pinned EDCM producer are inspected +# then: every semantic construction field is identical before Stack constructs an origin +# class: provenance_contract +# === END CONTRACTS === + +from __future__ import annotations +from dataclasses import asdict, dataclass +from hashlib import sha256 +import json +from pathlib import Path +import sqlite3 + +from .full_construct_run import _assert_schema_boundary, _definition_runs, _logical_receipt +from .hyperspace_construct import ( + V2_MANIFEST_RECEIPT, + glyph_inventory, + promote_glyph, + promote_word, +) + +SCHEMA = "english-gonol.edcm-metric-origin-set" +VERSION = "0.2.0" +FIXTURE = Path(__file__).resolve().parents[1] / "EDCM_METRIC_ORIGINS_SOURCE.json" +BASE = FIXTURE.parent / "BASE.json" +# Bind the complete source projection, not only a caller-supplied commit label. +FIXTURE_SHA256 = "cd3d384399da3029833e8f1cba993e4571cfcd2dd605e3ac44869de85aba43d3" + + +def _canonical(value: object) -> bytes: + return json.dumps( + value, sort_keys=True, ensure_ascii=False, + separators=(",", ":"), allow_nan=False, + ).encode("utf-8") + + +@dataclass(frozen=True, slots=True) +class OriginComponent: + ordinal: int + kind: str + surface: str + axis_origin: str + axis_index: int | None + identity: str + + +@dataclass(frozen=True, slots=True) +class MetricOriginSet: + metric_id: str + origin_id: str + producer_repository: str + producer_commit: str + construct_receipt: str + source_text: str + components: tuple[OriginComponent, ...] + closed: bool + unresolved: tuple[str, ...] + receipt_sha256: str + + def _payload(self) -> dict[str, object]: + return { + "schema": SCHEMA, + "version": VERSION, + "metric_id": self.metric_id, + "origin_id": self.origin_id, + "producer_repository": self.producer_repository, + "producer_commit": self.producer_commit, + "construct_receipt": self.construct_receipt, + "source_text": self.source_text, + "components": [asdict(x) for x in self.components], + "closed": self.closed, + "unresolved": list(self.unresolved), + } + + def to_dict(self) -> dict[str, object]: + return {**self._payload(), "receipt_sha256": self.receipt_sha256} + + +def load_metric_origin_specs(path: Path = FIXTURE) -> dict[str, object]: + content = Path(path).read_bytes() + if sha256(content).hexdigest() != FIXTURE_SHA256: + raise ValueError("EDCM metric-origin fixture digest mismatch") + data = json.loads(content) + if ( + data.get("schema") != "edcm.metric-origin-spec-fixture" + or data.get("version") != "0.3.0" + ): + raise ValueError("unsupported EDCM metric-origin fixture") + registered = json.loads(BASE.read_text(encoding="utf-8"))["metric_origin_source"] + if (data.get("producer_repository") != registered["repository"] + or data.get("producer_commit") != registered["commit"]): + raise ValueError("unregistered EDCM metric-origin producer") + return data + + +def _emit( + common: dict[str, object], + *, + components: tuple[OriginComponent, ...], + closed: bool, + unresolved: tuple[str, ...], +) -> MetricOriginSet: + payload = { + "schema": SCHEMA, + "version": VERSION, + **common, + "components": [asdict(x) for x in components], + "closed": closed, + "unresolved": list(unresolved), + } + receipt = sha256(_canonical(payload)).hexdigest() + return MetricOriginSet( + **common, + components=components, + closed=closed, + unresolved=unresolved, + receipt_sha256=receipt, + ) + + +def build_metric_origin_set( + state_dir: Path, + metric_id: str, + *, + fixture_path: Path = FIXTURE, +) -> MetricOriginSet: + source = load_metric_origin_specs(fixture_path) + specs = source["specs"] + if metric_id not in specs: + raise KeyError(f"unknown metric origin {metric_id!r}") + spec = specs[metric_id] + unresolved = tuple(spec.get("unresolved", ())) + terms = tuple(spec.get("construction_terms", ())) + source_text = " ".join(terms) + + if spec["standing"] != "resolved": + common = { + "metric_id": metric_id, + "origin_id": f"O_M({metric_id})", + "producer_repository": source["producer_repository"], + "producer_commit": source["producer_commit"], + "construct_receipt": "hmmm", + "source_text": source_text, + } + return _emit(common, components=(), closed=False, unresolved=unresolved) + + if not terms or any(not isinstance(term, str) or not term for term in terms): + raise ValueError(f"metric {metric_id}: resolved origin requires exact construction terms") + + db_path = Path(state_dir) / "construct.db" + if not db_path.exists(): + raise ValueError(f"construct.db not found under {state_dir}") + db = sqlite3.connect(f"file:{db_path}?mode=ro", uri=True) + try: + _assert_schema_boundary(db) + observed_receipt = _logical_receipt(db) + if observed_receipt != V2_MANIFEST_RECEIPT: + raise ValueError( + f"metric {metric_id}: construct receipt mismatch; " + f"expected {V2_MANIFEST_RECEIPT}, got {observed_receipt}" + ) + inventory = glyph_inventory(db) + components: list[OriginComponent] = [] + for ordinal, (kind, surface, _start, _end) in enumerate(_definition_runs(source_text)): + if kind == "word": + row = db.execute( + "SELECT id FROM words WHERE surface = ?", (surface,) + ).fetchone() + if row is None: + raise ValueError( + f"metric {metric_id}: unadmitted exact word surface {surface!r}" + ) + word, axis = promote_word(db, row[0]) + components.append( + OriginComponent( + ordinal, "word", surface, "O_W", axis, f"word:{word.word_id}" + ) + ) + else: + glyph, axis = promote_glyph(db, inventory, surface) + components.append( + OriginComponent( + ordinal, "glyph", surface, "O_G", axis, f"glyph:{glyph.identity}" + ) + ) + finally: + db.close() + + common = { + "metric_id": metric_id, + "origin_id": f"O_M({metric_id})", + "producer_repository": source["producer_repository"], + "producer_commit": source["producer_commit"], + "construct_receipt": observed_receipt, + "source_text": source_text, + } + return _emit( + common, + components=tuple(components), + closed=True, + unresolved=unresolved, + ) + + +__all__ = [ + "SCHEMA", + "VERSION", + "OriginComponent", + "MetricOriginSet", + "load_metric_origin_specs", + "build_metric_origin_set", +] diff --git a/research/english-gonol/tests/test_edcm_metric_origins.py b/research/english-gonol/tests/test_edcm_metric_origins.py new file mode 100644 index 00000000..8aa7ace2 --- /dev/null +++ b/research/english-gonol/tests/test_edcm_metric_origins.py @@ -0,0 +1,294 @@ +# === CHECKS === +# id: check_metric_origin_instrument_boundary +# proves: metric_origin_words_define_instrument_not_evidence +# call: self::test_origin_record_contains_no_measurement_value +# requires: python3 +# timeout: 10 +# mutates: none +# cleanup: none +# +# id: check_metric_origin_order_provenance +# proves: metric_origin_preserves_order_identity_provenance +# call: self::test_resolved_origin_uses_word_and_glyph_axes_in_order +# requires: python3 +# timeout: 10 +# mutates: temporary sqlite fixture +# cleanup: pytest tmp_path +# +# id: check_metric_origin_construct_identity +# proves: metric_origin_preserves_order_identity_provenance +# call: self::test_wrong_construct_receipt_fails_closed +# requires: python3 +# timeout: 10 +# mutates: temporary sqlite fixture +# cleanup: pytest tmp_path +# +# id: check_metric_origin_hmmm +# proves: metric_origin_unresolved_fails_open_as_hmmm_not_closed +# call: self::test_unresolved_origin_does_not_construct_components +# requires: python3 +# timeout: 10 +# mutates: none +# cleanup: none +# +# id: check_metric_origin_receipt_schema +# proves: metric_origin_receipt_binds_schema +# call: self::test_receipt_hashes_complete_payload_except_receipt +# requires: python3 +# timeout: 10 +# mutates: temporary sqlite fixture +# cleanup: pytest tmp_path +# id: check_metric_origin_pinned_corpus_admission +# proves: metric_origin_terms_admitted_by_pinned_corpus +# call: self::test_all_resolved_terms_are_admitted_by_pinned_oewn +# requires: python3, PyYAML, exact OEWN 2025 source +# timeout: 60 +# mutates: none +# cleanup: none +# id: check_metric_origin_source_fixture +# proves: metric_origin_source_fixture_matches_pinned_edcm +# call: self::test_stack_fixture_matches_exact_edcm_producer +# requires: python3, exact EDCM metric-origin producer +# mutates: none +# cleanup: none +# === END CHECKS === + +from hashlib import sha256 +import importlib.util +import json +import os +import sqlite3 +import subprocess +import sys +from pathlib import Path + +import pytest + +import english_gonol.edcm_metric_origins as origins +from english_gonol.hyperspace_construct import V2_MANIFEST_RECEIPT +from english_gonol.full_construct_run import _collect_surfaces, verify_replay +from english_gonol.language.source import load_oewn_2025, OEWN_COMMIT + + +def _fixture(tmp_path: Path): + path = tmp_path / "source.json" + path.write_bytes(origins.FIXTURE.read_bytes()) + return path + + +def _source_root(variable): + root = os.environ.get(variable) + if not root: + if os.environ.get("REQUIRE_METRIC_ORIGIN_SOURCES") == "1": + pytest.fail(f"required provenance source missing: {variable}") + pytest.skip(f"{variable} not supplied for optional local replay") + return Path(root) + + +def _verify_checkout(root, commit, paths): + assert subprocess.check_output(["git", "-C", str(root), "rev-parse", "HEAD"], text=True).strip() == commit + subprocess.run(["git", "-C", str(root), "diff", "--exit-code", "HEAD", "--", *paths], check=True) + + +def _db(tmp_path: Path): + db=sqlite3.connect(tmp_path/"construct.db") + db.executescript(""" + CREATE TABLE characters (id INTEGER PRIMARY KEY, scalar TEXT, public_position INTEGER); + CREATE TABLE words (id INTEGER PRIMARY KEY, surface TEXT); + CREATE TABLE word_characters (word_id INTEGER, ordinal INTEGER, character_id INTEGER); + """) + chars={} + next_id=1 + words=["fixation","persistence","repetition"] + for surface in words: + for ch in surface+" ": + if ch not in chars: + chars[ch]=next_id + db.execute("INSERT INTO characters VALUES (?,?,NULL)",(next_id,ch)) + next_id+=1 + for wid,surface in enumerate(words,1): + db.execute("INSERT INTO words VALUES (?,?)",(wid,surface)) + for ordinal,ch in enumerate(surface): + db.execute("INSERT INTO word_characters VALUES (?,?,?)",(wid,ordinal,chars[ch])) + db.commit(); db.close() + + +def _verified(monkeypatch): + monkeypatch.setattr(origins, "_assert_schema_boundary", lambda _db: None) + monkeypatch.setattr(origins, "_logical_receipt", lambda _db: V2_MANIFEST_RECEIPT) + + +def test_resolved_origin_uses_word_and_glyph_axes_in_order(tmp_path, monkeypatch): + _db(tmp_path); _verified(monkeypatch) + record=origins.build_metric_origin_set(tmp_path,"F",fixture_path=_fixture(tmp_path)) + assert record.closed + assert record.construct_receipt==V2_MANIFEST_RECEIPT + assert record.source_text=="fixation persistence repetition" + assert record.components[0].axis_origin=="O_W" + assert any(x.axis_origin=="O_G" and x.surface==" " for x in record.components) + assert record.producer_repository=="The-Interdependency/edcm" + assert "maintained implementation is a lexical structural proxy, not embedding similarity" in record.unresolved + assert record.origin_id == "O_M(F)" + + +def test_origin_record_contains_no_measurement_value(tmp_path, monkeypatch): + _db(tmp_path); _verified(monkeypatch) + record=origins.build_metric_origin_set(tmp_path,"F",fixture_path=_fixture(tmp_path)) + keys=record.to_dict() + assert "value" not in keys + assert "measurement" not in keys + assert "score" not in keys + assert record.source_text=="fixation persistence repetition" + + +def test_wrong_construct_receipt_fails_closed(tmp_path, monkeypatch): + _db(tmp_path) + monkeypatch.setattr(origins, "_assert_schema_boundary", lambda _db: None) + monkeypatch.setattr(origins, "_logical_receipt", lambda _db: "0"*64) + with pytest.raises(ValueError,match="construct receipt mismatch"): + origins.build_metric_origin_set(tmp_path,"F",fixture_path=_fixture(tmp_path)) + + +def test_unresolved_origin_does_not_construct_components(tmp_path): + record=origins.build_metric_origin_set( + tmp_path,"O",fixture_path=_fixture(tmp_path) + ) + assert record.closed is False + assert record.components==() + assert record.construct_receipt=="hmmm" + assert record.unresolved==("marker canon says Overextension; compute.py says Overconfidence",) + assert record.origin_id == "O_M(O)" + + +def test_receipt_hashes_complete_payload_except_receipt(tmp_path, monkeypatch): + _db(tmp_path); _verified(monkeypatch) + record=origins.build_metric_origin_set(tmp_path,"F",fixture_path=_fixture(tmp_path)) + payload=record.to_dict() + receipt=payload.pop("receipt_sha256") + expected=sha256(json.dumps( + payload,sort_keys=True,ensure_ascii=False,separators=(",",":"),allow_nan=False + ).encode("utf-8")).hexdigest() + assert receipt==expected + assert payload["schema"]==origins.SCHEMA + assert payload["version"]==origins.VERSION + + +def test_all_resolved_terms_are_admitted_by_pinned_oewn(): + root = _source_root("OEWN_SOURCE_ROOT") + _verify_checkout(root, OEWN_COMMIT, ["."]) + snapshot=load_oewn_2025(root) + words,_characters=_collect_surfaces(snapshot) + admitted=set(words) + fixture=origins.load_metric_origin_specs() + missing={} + for metric,spec in fixture["specs"].items(): + if spec["standing"]!="resolved": + continue + absent=[term for term in spec["construction_terms"] if term not in admitted] + if absent: + missing[metric]=absent + assert missing=={} + + +def test_stack_fixture_matches_exact_edcm_producer(): + root = _source_root("EDCM_METRIC_ORIGIN_ROOT") + fixture=origins.load_metric_origin_specs() + _verify_checkout(root, fixture["producer_commit"], ["edcm"] ) + module_path=Path(root)/"edcm"/"metric_origin_spec.py" + spec=importlib.util.spec_from_file_location("_pinned_edcm_metric_origin_spec",module_path) + assert spec is not None and spec.loader is not None + module=importlib.util.module_from_spec(spec) + sys.modules[spec.name]=module + spec.loader.exec_module(module) + fixture=origins.load_metric_origin_specs() + assert fixture["producer_commit"]=="ce645e4b3cce0308676837f60bed118fa74f23ac" + assert tuple(fixture["specs"])==tuple(module.METRIC_ORIGIN_SPECS) + for metric,source_spec in module.METRIC_ORIGIN_SPECS.items(): + record=fixture["specs"][metric] + assert record["surface_terms"]==list(source_spec.surface_terms) + assert record["construction_terms"]==list(source_spec.construction_terms) + assert record["semantic_definition"]==source_spec.semantic_definition + assert record["standing"]==source_spec.standing + assert record["measurement_alignment"]==source_spec.measurement_alignment + assert record["unresolved"]==list(source_spec.unresolved) + + +@pytest.mark.parametrize("mutation", ["repository", "commit", "terms", "standing"]) +def test_unregistered_or_modified_fixture_fails_closed(tmp_path, mutation): + path = _fixture(tmp_path) + source = json.loads(path.read_text()) + if mutation == "repository": + source["producer_repository"] = "someone/else" + elif mutation == "commit": + source["producer_commit"] = "a" * 40 + elif mutation == "terms": + source["specs"]["F"]["construction_terms"] = ["invented"] + else: + source["specs"]["O"]["standing"] = "resolved" + path.write_text(json.dumps(source)) + with pytest.raises(ValueError, match="fixture digest mismatch"): + origins.build_metric_origin_set(tmp_path, "F", fixture_path=path) + + +def test_registered_producer_and_all_projections_agree(): + workspace = origins.FIXTURE.parent + stack = workspace.parents[1] + fixture = origins.load_metric_origin_specs() + producer = fixture["producer_commit"] + graph = json.loads((workspace / "docs/work-graphs/metric-origin-space-v0.json").read_text()) + participant = next(x for x in graph["repositories"] if x["repository"] == fixture["producer_repository"]) + assert participant["commit"] == producer + digest = sha256(json.dumps({k: graph[k] for k in ("repositories", "boundaries")}, sort_keys=True, separators=(",", ":")).encode()).hexdigest() + assert graph["work_graph_sha256"] == digest + manifest = json.loads((stack / "stack-manifest.json").read_text()) + participant = next(x for x in manifest["research_participants"] if x.get("participant_id") == "edcm-metric-origin-source") + assert participant["commit"] == producer + assert producer in (stack / "STACK_MANIFEST.md").read_text() + + +def test_required_provenance_source_cannot_skip(monkeypatch): + monkeypatch.setenv("REQUIRE_METRIC_ORIGIN_SOURCES", "1") + monkeypatch.delenv("OEWN_SOURCE_ROOT", raising=False) + with pytest.raises(pytest.fail.Exception, match="required provenance source missing"): + _source_root("OEWN_SOURCE_ROOT") + + +def test_full_construct_origins_bind_to_pinned_edcm(): + state_dir = _source_root("ENGLISH_GONOL_FULL_CONSTRUCT_ROOT") + edcm_root = _source_root("EDCM_METRIC_ORIGIN_ROOT") + fixture = origins.load_metric_origin_specs() + _verify_checkout(edcm_root, fixture["producer_commit"], ["edcm"]) + manifest = verify_replay(state_dir) + assert manifest["receipt_sha256"] == V2_MANIFEST_RECEIPT + records = {metric: origins.build_metric_origin_set(state_dir, metric).to_dict() + for metric in fixture["specs"]} + for metric, record in records.items(): + payload = {k: v for k, v in record.items() if k != "receipt_sha256"} + assert sha256(origins._canonical(payload)).hexdigest() == record["receipt_sha256"] + assert record["origin_id"] == f"O_M({metric})" + assert record["closed"] is (metric not in {"O", "L"}) + # A subprocess prevents an already-imported editable EDCM from shadowing + # the exact producer checkout under test. + result = subprocess.run( + [sys.executable, "-c", """ +import json, sys +from dataclasses import asdict +from edcm.measurement import compute_transcript, parse_transcript +from edcm.semantic_metric_space import build_semantic_metric_space, bind_round_metrics +origins = json.load(sys.stdin) +space = build_semantic_metric_space(origins) +assert space.unresolved_metrics == ('O', 'L') +assert not space.complete +metrics = compute_transcript(parse_transcript('A: State the constraint.\\nB: Recorded.'))[0] +rows = bind_round_metrics(metrics, space, evidence_receipt='synthetic-transcript:full-replay-test') +assert [row.value for row in rows] == metrics.vector() +assert all(row.semantic_projection == 'hmmm' for row in rows) +print(json.dumps([asdict(row) for row in rows], allow_nan=False)) +"""], cwd=edcm_root, input=json.dumps(records), text=True, capture_output=True, + env={**os.environ, "PYTHONPATH": str(edcm_root)}, check=True, + ) + evidence = {"producer_commit": fixture["producer_commit"], + "construct_receipt": manifest["receipt_sha256"], + "origin_records": records, "readouts": json.loads(result.stdout), + "unresolved_metrics": ["O", "L"], "semantic_projection": "hmmm"} + (state_dir / "metric-origin-replay.json").write_text(json.dumps(evidence, indent=2) + "\n") diff --git a/stack-manifest.json b/stack-manifest.json index 3f6f7fb6..cd2d78da 100644 --- a/stack-manifest.json +++ b/stack-manifest.json @@ -1,7 +1,7 @@ { "schema": "the-interdependency.stack-manifest", "version": "1.1.0", - "work_graph_sha256": "7384687cde8e9d18a1019fecd62adbaa6278930bb556546db05062ef4a348f0b", + "work_graph_sha256": "f0ce9606681cc053d9dcbb010805a932290207d49a5d8714297b8c3ce455ec41", "repositories": [ { "repository": "The-Interdependency/skill-lib", @@ -330,6 +330,16 @@ "relation": "exact installed wheel consumer via research/zfae/UCHC_INPUT.json; no fixed-width semantic projection or neural readiness promotion", "canonical_release": false, "authority_transfer": false + }, + { + "workspace": "research/english-gonol/", + "participant_id": "edcm-metric-origin-source", + "repository": "The-Interdependency/edcm", + "commit": "ce645e4b3cce0308676837f60bed118fa74f23ac", + "authority": "EDCM semantic metric-origin definitions and measurement-rule alignment", + "relation": "exact semantic-origin producer consumed by Stack English; does not refresh libs/edcm or transfer measurement authority", + "canonical_release": false, + "authority_transfer": false } ] }