Compare commits

..

9 commits

590 changed files with 1307 additions and 24277 deletions

View file

@ -26,7 +26,7 @@ The cognitive path is centered on:
- `teaching/correction.py`, `teaching/review.py`, `teaching/store.py`
- `evals/*`
- `calibration/*`
- `packs/data/en_core_cognition_v1`
- `language_packs/data/en_core_cognition_v1`
The runtime response contract is documented in `docs/runtime_contracts.md`.
Follow it.
@ -42,7 +42,7 @@ versor_condition(F) < 1e-6
Allowed construction/closure sites:
- `ingest/gate.py`
- `packs/compiler.py` / vocabulary construction
- `language_packs/compiler.py` / vocabulary construction
- `algebra/versor.py`
Forbidden hot-path repair sites:

View file

@ -44,7 +44,7 @@ jobs:
enable-cache: true
- name: install dependencies
run: uv sync --locked --extra dev
run: uv pip install -e ".[dev]" pyyaml
- name: run contemplation cycle
id: run

View file

@ -1,25 +1,16 @@
name: full-pytest
# Post-merge FAST lane — runs on every push to main.
# Post-merge validation — runs the full pytest suite on every push to main.
# PRs are gated by the faster smoke workflow (smoke.yml); this catches
# anything outside the smoke suite within minutes of merge.
#
# Marker: -m "not quarantine and not slow"
# ~9.5k unit/integration tests; excludes the slow registry in conftest.py
# (soak / bench / proof / register-matrix; ~912 tests including the 16 min
# phase2 fixture floor).
#
# Why "full-pytest" still names this file:
# Keep the workflow id stable for Forgejo required-check / history matching.
# The job display name and this comment state the true contract: FAST on main.
# The complete non-quarantine suite runs in nightly-full-pytest.yml.
#
# PR gate: smoke.yml (small critical subset).
# Lane pins: lane-shas.yml.
# Full soak: nightly-full-pytest.yml (schedule + workflow_dispatch).
# Quarantined tests are excluded via the conftest.py QUARANTINE registry.
# The intent is a ratchet: once a test is removed from the registry it
# must keep passing on this gate.
#
# See:
# conftest.py — QUARANTINE + SLOW_FILES / SLOW_TESTS registries
# docs/testing-lanes.md — lane commands and CI policy (SSoT)
# docs/ci-optimization.md — runner bottleneck + capacity notes
# conftest.py — the QUARANTINE registry (one entry per quarantined test)
# docs/test-debt-quarantine.md — cluster diagnoses + removal policy
on:
push:
@ -34,10 +25,9 @@ concurrency:
jobs:
pytest:
name: fast pytest (-m "not quarantine and not slow" -n 2)
name: full pytest (-m "not quarantine" -n 2)
runs-on: ubuntu-latest
# Headroom over ~9.5 min parallel on a 10-core host; Act 2-vCPU is slower.
timeout-minutes: 30
timeout-minutes: 45
steps:
- name: checkout
@ -53,14 +43,14 @@ jobs:
- name: install dependencies
run: |
uv sync --locked --extra dev
uv pip install -e ".[dev]" pyyaml
- name: pytest (parallel, quarantine and slow excluded)
- name: pytest (parallel, quarantine excluded)
env:
PYTHONPATH: ${{ github.workspace }}
CORE_SHOWCASE_SKIP_BUDGET: "1"
run: |
uv run pytest -m "not quarantine and not slow" -n 2 --tb=short -q --maxfail=10
uv run pytest -m "not quarantine" -n 2 --tb=short -q --maxfail=10
- name: report quarantine size (informational)
if: always()

View file

@ -1,20 +1,12 @@
name: lane-shas
# Verify that every ADR-0092..0104 lane produces its pinned SHA-256
# Verify that every ADR-0092..0099 lane produces its pinned SHA-256
# report. A failing job means a lane's deterministic output changed
# without an explicit ADR-tracked pin update via:
#
# python scripts/verify_lane_shas.py --update
#
# Single source of truth for the pinned values is scripts/verify_lane_shas.py.
#
# PR path policy (job-level, not workflow-level):
# Pin bytes can move from Python, packs, eval fixtures/corpora, teaching
# corpora, dependency pins, CLAIMS.md, or this workflow. When none of those
# paths change on a PR, we skip the multi-minute runners and exit success so
# a required check never sits "Waiting" forever (workflow-level `paths:`
# would omit the job entirely and hang required status checks).
# Main pushes always verify.
on:
push:
@ -33,81 +25,40 @@ jobs:
verify:
name: verify pinned lane SHAs
runs-on: ubuntu-latest
timeout-minutes: 45
timeout-minutes: 20
steps:
- name: checkout
uses: actions/checkout@v4
with:
# Need base..head for PR path detection.
fetch-depth: 0
fetch-depth: 1
- name: detect pin-relevant paths
id: paths
shell: bash
run: |
set -euo pipefail
# Always verify on main pushes.
if [ "${{ github.event_name }}" = "push" ]; then
echo "run=true" >> "$GITHUB_OUTPUT"
echo "Pin-relevant path check: always run on push"
exit 0
fi
BASE="${{ github.event.pull_request.base.sha }}"
HEAD="${{ github.event.pull_request.head.sha }}"
# Paths that can change pin bytes or CLAIMS generation inputs.
# Keep in sync with docs/testing-lanes.md § CI policy.
PATTERN='(\.py$|^packs/|^evals/|^teaching/|^CLAIMS\.md$|^pyproject\.toml$|^uv\.lock$|^\.github/workflows/lane-shas\.yml$)'
if git diff --name-only "$BASE" "$HEAD" | grep -E "$PATTERN" >/dev/null; then
echo "run=true" >> "$GITHUB_OUTPUT"
echo "Pin-relevant paths changed; running lane SHA verification"
git diff --name-only "$BASE" "$HEAD" | grep -E "$PATTERN" || true
else
echo "run=false" >> "$GITHUB_OUTPUT"
echo "No pin-relevant paths changed; skipping lane SHA verification (job still green)"
fi
# setup-uv (not actions/setup-python) provisions Python on the aarch64
# self-hosted runner; actions/setup-python has no arm64 build for the
# pinned 3.12.13. Matches smoke.yml / full-pytest.yml.
- name: set up uv
if: steps.paths.outputs.run == 'true'
uses: astral-sh/setup-uv@v5
- name: set up python
uses: actions/setup-python@v5
with:
python-version: '3.12.13'
enable-cache: true
cache: 'pip'
- name: install dependencies
if: steps.paths.outputs.run == 'true'
run: |
uv sync --locked
python -m pip install --upgrade pip
pip install -e . pyyaml pytest
- name: verify lane SHAs
if: steps.paths.outputs.run == 'true'
env:
PYTHONPATH: ${{ github.workspace }}
# public_demo wall-clock is soft by default (see evals/public_demo/runner.py).
# Do not set CORE_SHOWCASE_HARD_BUDGET here — cold Act runners exceed 60s.
# Content cases (claims, determinism, pure composition) remain hard gates.
run: |
uv run python scripts/verify_lane_shas.py
python scripts/verify_lane_shas.py
- name: verify CLAIMS.md is current
if: steps.paths.outputs.run == 'true'
env:
PYTHONPATH: ${{ github.workspace }}
run: |
uv run python scripts/generate_claims.py --check
python scripts/generate_claims.py --check
- name: emit machine-readable report (on failure)
if: failure() && steps.paths.outputs.run == 'true'
if: failure()
env:
PYTHONPATH: ${{ github.workspace }}
run: |
uv run python scripts/verify_lane_shas.py --json || true
- name: skip notice
if: steps.paths.outputs.run != 'true'
run: |
echo "::notice title=lane-shas skipped::No pin-relevant paths in this PR; verification skipped (success)."
python scripts/verify_lane_shas.py --json || true

View file

@ -1,72 +0,0 @@
name: nightly-full-pytest
# Nightly FULL lane — complete non-quarantine suite including the slow registry.
#
# Marker: -m "not quarantine"
# Includes soak / bench / proof / register-matrix (SLOW_FILES + SLOW_TESTS).
# Intentionally off the PR and post-merge critical path so a single 2-vCPU
# Act runner is not held for 12h after every main push (see docs/ci-optimization.md).
#
# Risk owned here: a main merge can break slow tests until the next nightly
# (or a manual workflow_dispatch). Treat red nightlies as release-blocking
# debt; re-run via Actions → nightly-full-pytest → Run workflow after fixes.
#
# See docs/testing-lanes.md for the full CI policy.
on:
schedule:
# 02:00 UTC daily — off peak for human PR iteration.
- cron: '0 2 * * *'
workflow_dispatch:
permissions:
contents: read
concurrency:
group: nightly-full-pytest
cancel-in-progress: false
jobs:
pytest:
name: full pytest (-m "not quarantine" -n 2)
runs-on: ubuntu-latest
# Full suite parallel floor includes ~16 min phase2 fixture; thrashing on a
# 2-vCPU Act host has been observed well past 60 min. Prefer a red timeout
# only after a genuine hang, not under normal soak load.
timeout-minutes: 120
steps:
- name: checkout
uses: actions/checkout@v4
with:
fetch-depth: 1
ref: main
- name: set up uv
uses: astral-sh/setup-uv@v5
with:
python-version: '3.12.13'
enable-cache: true
- name: install dependencies
run: |
uv sync --locked --extra dev
- name: pytest (parallel, full suite, quarantine excluded)
env:
PYTHONPATH: ${{ github.workspace }}
CORE_SHOWCASE_SKIP_BUDGET: "1"
run: |
uv run pytest -m "not quarantine" -n 2 --tb=short -q --maxfail=10
- name: report quarantine size (informational)
if: always()
env:
PYTHONPATH: ${{ github.workspace }}
run: |
uv run python -c "
import sys
sys.path.insert(0, '.')
from conftest import QUARANTINE
print(f'::notice title=Quarantine size::{len(QUARANTINE)} tests currently quarantined. Goal: shrink this number.')
"

View file

@ -70,7 +70,7 @@ jobs:
enable-cache: true
- name: install dependencies
run: uv sync --locked --extra dev
run: uv pip install -e ".[dev]"
- name: resolve review date
id: date

View file

@ -7,10 +7,9 @@ name: smoke
# — ratified packs diverge directionally; pack-invariant refusal floor; no
# fabrication). The falsifiability lane adds ~4 min but blocks-on-regression.
#
# Post-merge on main: full-pytest.yml runs the FAST lane
# (-m "not quarantine and not slow"). Soak / proof / register-matrix coverage
# is nightly-full-pytest.yml (not on the PR critical path).
# See docs/testing-lanes.md.
# Full pytest runs post-merge to main (see full-pytest.yml).
# Regressions caught here block the PR; anything outside the smoke
# suite is caught on main within minutes of merge.
on:
pull_request:
@ -43,7 +42,7 @@ jobs:
- name: install dependencies
run: |
uv sync --locked --extra dev
uv pip install -e ".[dev]" pyyaml
- name: pytest smoke suite
env:

4
.gitignore vendored
View file

@ -15,6 +15,7 @@ workbench_data/*
core-rs/target/
core-rs/Cargo.lock
uv.lock
# Environment secrets — never commit real keys
.env
@ -84,6 +85,3 @@ skills-lock.json
# Per-life backup checkpoint dirs are runtime-generated, not source.
engine_state/_life_backup_*/
# Local MCP configuration (contains local tokens)
.mcp.json

View file

@ -4,16 +4,6 @@ This is the canonical governance file for this repository.
If any provider-specific file (`CLAUDE.md`, `GEMINI.md`, or future agent files) overlaps with this document, `AGENTS.md` wins. Provider files should only contain minimal startup and workflow notes, not alternate architecture or alternate invariants.
## Session Continuity (lightweight, session-break only)
When you are approaching a stopping point, known pause, or session break:
- Create a file named `session-break-summary-<YYYY-MM-DD-HHMM>.md` (precise datetime recommended) at the repo root or in `docs/sessions/`.
- Keep it short and actionable: current branch/state, what was just completed, exact next concrete steps, any open invariants/tests/hazards, and key files to re-read.
- At the **start of any new session** (or subagent): Quickly scan for any recent `session-break-summary-*.md` files. Read the most relevant one if present.
- Once you have resumed the work and continued past the break point, **delete the file**. Its only purpose is temporary continuity for the immediate next pickup.
The previous heavy `HANDOFF-*.md` / formal handoff machinery is retired (see history in git and docs/handoffs/ for old artifacts).
## Mission
CORE is a deterministic cognitive engine under construction.
@ -69,7 +59,7 @@ Fix the operator or construction boundary that violated it.
### Allowed normalization boundaries
Normalization / closure / canonicalization belongs only at explicit construction or algebra boundaries, such as:
- `ingest/gate.py`
- `packs/compiler.py`
- `language_packs/compiler.py`
- `algebra/versor.py`
- `sensorium/*/canonical.py`
- `session/context.py` for session-scoped **semantic anchoring** of the field toward the session concept-attractor (the anchor pull, hemisphere consistency). Allowed ONLY because every such op (1) preserves `versor_condition` BY CONSTRUCTION — composed from `rotor_power` / `word_transition_rotor` / `versor_apply` on the Spin manifold, never a post-hoc `unitize`/grade-projection — AND (2) carries semantic meaning in the cognitive model.
@ -128,7 +118,7 @@ Do not introduce new local prose parsers inside derivation organs unless explici
Before editing:
1. Read this file.
2. Read `docs/specs/runtime_contracts.md`.
3. Check for any recent `session-break-summary-*.md` files (see top-level section above) and read the relevant one if present.
3. Read the latest recent `HANDOFF-*.md` if relevant.
4. Confirm repo root and inspect working tree state.
5. Run the smallest relevant validation lane.
@ -139,66 +129,7 @@ For non-trivial edits:
- keep changes small and load-bearing
- If working in Arena/parallel subagent mode, each subagent must independently satisfy `versor_condition` and results must be reconciled before merge. No subagent output becomes another subagent's unchecked input.
## Reasoning and Problem-Solving Discipline
LLMs are not reliably intelligent by default. CORE exists partly to fix that.
Agents working in this repository must hold themselves to the following protocol
on every non-trivial task. Skipping steps produces confident-sounding work that
is wrong in load-bearing ways.
### The Protocol
**1. Read the code — never reason from names or structure alone.**
Before forming any opinion about a module, read its implementation. Trace its
imports and call sites. Identify what invariant it is protecting. A file named
`pass_manager.py` tells you nothing until you have read it.
**2. Find the shape — what underlying structure does this problem have?**
Before proposing a solution, identify the repeating structure the problem
expresses. The solution should make that structure visible, not paper over it.
Duplication is a symptom; the cause is an unnamed shape.
**3. Rank by leverage — genius-to-effort, not ease.**
When multiple improvements are possible, rank them explicitly by how much
cognitive/structural load they remove vs. how much effort they require. Implement
in that order. An agent that implements low-leverage changes first and skips
high-leverage ones has optimized for the wrong thing.
**4. Enumerate changes precisely — no ambiguity about what goes where.**
Before committing, state every change, which file it lives in, and why. The
commit message must reflect this. Vague commits ("refactor", "cleanup") are
not acceptable on load-bearing modules.
**5. Prove against real claims — not abstract correctness.**
"Tests pass" is not proof. Identify which specific pinned assertion in
`CLAIMS.md` the change must preserve or enable. State the SHA-256 lane or
`core test --suite` invocation that verifies it. If no existing lane covers
the change, say so explicitly — that is itself a finding.
**6. Connect to the cognitive model — what does this do for the system's reasoning?**
Every non-trivial change must be articulable in terms of what it does for
CORE's actual cognition path:
`listen → comprehend → recall → think → articulate → learn → replay`
If you cannot state what cognitive property the change strengthens, the change
is not yet understood well enough to ship.
**7. Commit with discipline — right branch, right invariant, right lane.**
Confirm repo state and branch before every commit. Never commit directly to
`main` unless the change is documentation or governance (like this one).
State which invariant the change protects. Run the smallest validation lane
that proves the change before declaring it done.
### The Failure Modes This Prevents
- Reasoning from file names instead of reading the code → wrong analysis
- Proposing solutions before finding the underlying shape → solutions that
recreate the same problem in a different form
- Implementing easy changes first → high-leverage work never gets done
- Vague success criteria → regressions that pass "tests" but break real claims
- Shipping changes that can't be connected to the cognitive model → architectural
drift away from CORE's mission
## Repository topology discipline
### Repository topology discipline
Before calling a directory, module, or file stale/redundant, classify its
intrinsic role:
- runtime boundary
@ -232,25 +163,6 @@ Before branch movement or edits:
- Establish a clean current `main`.
- Prefer a fresh worktree from `origin/main` for non-trivial implementation.
### Git and Forgejo Setup
**CRITICAL**: This repository is hosted on a private **Forgejo** server, NOT GitHub. GitHub is deprecated for core work and CI testing.
Our sole remote and CI/CD platform is **core-gitquarters.acbcontent.org**.
- **DO NOT** use the `gh` (GitHub) CLI for normal work or PR management.
- **DO NOT** attempt to push, pull, or clone from `github.com` for developer/agent loops.
- **USE** the provided Forgejo MCP tools if available.
- **USE** the `tea` CLI (Gitea/Forgejo CLI) for issues, PRs, and repository management targeting `core-gitquarters.acbcontent.org`.
### Local-First CI Validation Protocol
To optimize server resources and bypass external CI billing dependencies, all agents and developers must run validation suites locally.
- **Pre-Push Gate:** Before pushing any branch to Forgejo, you **MUST** run the `smoke` test suite locally using:
```bash
uv run core test --suite smoke -q
```
Ensure all 108+ tests pass. Pushing broken code is a critical protocol violation.
- **Pre-Merge Gate:** Before proposing a merge or requesting a review on a PR, you **MUST** run the larger validation suite relevant to your changes (e.g. `uv run core test --suite cognition` or `uv run core test --suite algebra`).
- **PR Documentation:** When creating a PR on Forgejo (via `tea pr create`), document the local test execution in the PR description, matching this format:
`[Verification]: Smoke suite passed locally (<run_duration>s, <test_count> passed)`
### Pre-Edit Sweep & Versor Coherence Guardian Protocol
Before modifying any module in `algebra/`, `field/`, `vault/`, or `generate/`:
- Trace every import of the target module and identify all callers.
@ -259,7 +171,7 @@ Before modifying any module in `algebra/`, `field/`, `vault/`, or `generate/`:
## Documentation Discipline
ADRs, session docs, audit artifacts, and temporary session-break summaries stay as Markdown (GitHub-flavored). Plain-text artifacts are diffable, greppable, and readable by every agent in the dispatch pipeline.
ADRs, session docs, audit artifacts, and handoff briefs stay as Markdown (GitHub-flavored). Plain-text artifacts are diffable, greppable, and readable by every agent in the dispatch pipeline.
Within Markdown, two GitHub-rendered features are sanctioned and otherwise sparingly used:
- Mermaid fenced blocks (` ```mermaid `) when a state machine, sequence, or dependency graph genuinely communicates more than prose. Inline, not in a sidecar file.

View file

@ -38,8 +38,8 @@ is a CI failure (`.github/workflows/lane-shas.yml`).
| ADR-0093 | `domain_contract_validation` | All ratified packs satisfy the 9 ADR-0091 contract predicates | `evals/domain_contract_validation/results/v1_dev.json` | `98ace04e3f02bbc5a8ad655bb6593c3f1ee64cb67014f1122fe6c3c85f48d22f` |
| ADR-0095 | `miner_loop_closure` | Miner-sourced proposals route through single reviewed teaching path | `evals/miner_loop_closure/results/v1_dev.json` | `9f071733abe7dcacf759f928548ce738fb639af3fd6e4c621a651b306d7e77ce` |
| ADR-0096 | `fabrication_control_summary` | Phantom endpoints / cross-pack non-bridges / sibling collapses refuse | `evals/fabrication_control/results/v1_summary.json` | `01e1b6b711141f2b4a14551d7df3ea482d8d6dd7b364a25c509f4f8d08cda8a8` |
| ADR-0098 | `demo_composition` | Demos compose from shipped modules; no parallel mechanism | `evals/demo_composition/results/v1_dev.json` | `e2ba2314d8768459fb6a8db082a4bbcf4107b5161d869804a4b2a33c3724081a` |
| ADR-0099 | `public_demo` | Public showcase runs deterministically under 30s; all claims supported | `evals/public_demo/results/v1_dev.json` | `7d8ba0dbae9287cfe0bf15d231fa78a75abc627121c14900439293e01e1cc1d3` |
| ADR-0098 | `demo_composition` | Demos compose from shipped modules; no parallel mechanism | `evals/demo_composition/results/v1_dev.json` | `3a3d09f3a87462737e615c2dd3481b9e13e5ff8fadee0043c37873494ded556d` |
| ADR-0099 | `public_demo` | Public showcase runs deterministically under 30s; all claims supported | `evals/public_demo/results/v1_dev.json` | `2895df080b91618aefc2df407c637ff419fbb6dae33233c90262688c103411ea` |
| ADR-0104 | `curriculum_loop_closure` | Curriculum-sourced proposals route through single reviewed teaching path | `evals/curriculum_loop_closure/results/v1_dev.json` | `b46d56b2d209172cc3ffaf3776dc8dcfe55093f13587c5cb67372be6dfa23e8d` |
| ADR-0131 | `math_teaching_corpus_v1` | Math teaching corpus replays deterministically; all chains pass exit criterion (correct_rate=1.0, wrong=0) | `evals/math_teaching_corpus/v1/report.json` | `eaf160d145da29f9050ede8d58bf111b0f651dd40aeae9201857d0b97e014dd4` |
| ADR-0206 | `deductive_logic_v1` | Propositional entailment scored against an independent truth-table oracle; dev+holdout+external 716/716 correct, wrong=0, refused=0 | `evals/deductive_logic/report.json` | `97a230949016e38d5e3f37a69e4245b320575ee70e5af92ff7607f7b05f74b5f` |

View file

@ -1,10 +1,11 @@
# CORE Agent Instructions for Claude
`AGENTS.md` is the canonical governance file. If this file conflicts, follow `AGENTS.md`.
`AGENTS.md` is the canonical governance file for this repo. If this file
conflicts with `AGENTS.md`, follow `AGENTS.md`.
Startup: read `AGENTS.md`, `docs/specs/runtime_contracts.md`, inspect working tree, use the smallest validation lane.
**CRITICAL**: Remote is `core-gitquarters.acbcontent.org`. Do not use GitHub/`gh` CLI. Use Forgejo tools/`gitea` CLI.
Claude-specific startup: read `AGENTS.md`, read
`docs/specs/runtime_contracts.md`, inspect the working tree, then use the
smallest validation lane that proves the change.
Before non-trivial edits, apply the protocol in `AGENTS.md`.
Do not place architecture, invariants, memory rules, or alternate workflow policy here. Update `AGENTS.md` instead.
Do not place architecture, invariants, memory rules, or alternate workflow
policy here. Update `AGENTS.md` instead.

View file

@ -1,10 +1,11 @@
# CORE Agent Instructions for Gemini
`AGENTS.md` is the canonical governance file. If this file conflicts, follow `AGENTS.md`.
`AGENTS.md` is the canonical governance file for this repo. If this file
conflicts with `AGENTS.md`, follow `AGENTS.md`.
Startup: read `AGENTS.md`, `docs/specs/runtime_contracts.md`, inspect working tree, use the smallest validation lane.
**CRITICAL**: Remote is `core-gitquarters.acbcontent.org`. Do not use GitHub/`gh` CLI. Use Forgejo tools/`gitea` CLI.
Gemini-specific startup: read `AGENTS.md`, read
`docs/specs/runtime_contracts.md`, inspect the working tree, then use the
smallest validation lane that proves the change.
Before non-trivial edits, apply the protocol in `AGENTS.md`.
Do not place architecture, invariants, memory rules, or alternate workflow policy here. Update `AGENTS.md` instead.
Do not place architecture, invariants, memory rules, or alternate workflow
policy here. Update `AGENTS.md` instead.

View file

@ -1,59 +1,11 @@
> [!IMPORTANT]
> **Repository Migration Notice:**
> The GitHub repository `AssetOverflow/core` is now essentially **Read Only**.
> The active open-source repository is available for cloning/forking at our new git headquarters:
> 🌐 **[core-gitquarters.acbcontent.org](https://core-gitquarters.acbcontent.org)** (along with new open-source projects coming down the pipeline).
>
> Please update your remotes and direct any issues, pull requests, or contributions to the new git headquarters.
# CORE-AI: Versor Engine
# CORE — A Deterministic Cognition Engine
A cognitive field system built on Cl(4,1) Conformal Geometric Algebra.
**CORE is a single-life, deterministic cognition engine in which a unified conformal-geometric substrate is the medium for memory, language, identity, and epistemics — governed so that it can earn autonomy from human oversight by proving reliability, never by asserting it.**
**Core invariant:** `||F * reverse(F) - 1||_F < 1e-6` at all times.
A unified Cl(4,1) conformal-geometric-algebra substrate serves as the common medium for **all modalities** (through CRDT-sharded, content-addressed, *exact*-recall memory), **all language** (through compiled linguistic manifolds where morphology and grammatical relation are *operators*, not tokens), **all identity** (as a fixed geometric subspace that content cannot rewrite — paraphrase-invariantly), and **all epistemics** (truth-status travels with every claim; admission is by coherence, not authority; the system publishes its own gaps and holds that discipline recursively over its own claims). A deterministic riskreward governor lets CORE earn its way out of human-in-the-loop supervision by accumulating a replayable, conservatively-bounded reliability ledger — while never self-authorizing, and always leaving a door open for monitoring and upgrades. Thermodynamics (energy, salience, surprise), topology (the manifold, holonomy, the CRDT semilattice), the scientific method (falsifiable proof obligations, sealed holdouts), and a theologicallinguistic philosophy of language (the *Logos* as the structuring principle recovered at every input boundary) are not decoration — each is load-bearing, and nothing is included without deliberate intent.
**Core invariant:** `‖F · reverse(F) 1‖_F < 1e-6` at all times. All state is a versor; all transitions are versor products; coherence is algebraic by construction — not monitored, not corrected.
> **Provisional Patent No. 64/080,054** · U.S. Patent and Trademark Office
> Independent research program · [core-gitquarters.acbcontent.org](https://core-gitquarters.acbcontent.org)
---
## What CORE Is Not — Read This Before Pattern-Matching
CORE reuses vocabulary from several established fields. **The words collide with things you already know; the architecture does not.** If you skim the concepts and file CORE under a category you recognize, you will be wrong in a specific, load-bearing way. This section exists to prevent that.
**CORE is not a geometric deep-learning model.** It shares the *words* "Clifford/geometric algebra" and "versor" with GATr, CGENN, and similar equivariant networks — but those are neural networks trained by gradient descent that *use* geometric algebra to get equivariance. CORE has **no neural network, no gradients, no learned weights, no training loss**. The geometry is not a feature space for a model to learn in; it is the deterministic medium in which cognition, memory, and governance invariants are *physically enforced*. There is nothing to train.
**CORE is not a vector database and its recall is not approximate nearest-neighbor.** The vault shares the *words* "inner-product recall" with ANN systems, but it is a **Delta-CRDT join-semilattice**: write-accumulation that is commutative, associative, and idempotent, content-addressed by IEEE-754 bit pattern so recall is **total, exact, and arrival-order-independent**. Exactness is not a naïve choice waiting to be replaced by an index at scale — it is the *enabling property* of cross-modal unification. Approximate recall would corrupt the geometry that lets any two modalities resonate in one manifold; an ANN index was deliberately *deleted* for exactly this reason.
**CORE is not an LLM, and not an LLM wrapper.** It generates language without sampling, temperature, beam search, or a softmax over subword tokens. Generation is a deterministic geometric walk, and where the walk could emit something inadmissible under the relation being asserted, the engine emits a **typed refusal** rather than a plausible-but-wrong token. There is no probabilistic decoder anywhere in the system. "Zero confabulation" is not a tuned abstention rate — it is a structural consequence of the same mechanism that makes the system truth-seeking.
**CORE is not a safety layer bolted onto a generative model.** There is no classifier downstream of a generator, no instruction-following prompt, no guardrail the model could in principle ignore. Identity is a geometric subspace; truth-status is a typed value carried by every admitted claim; the boundaries the system will never cross are enforced at the substrate. A system that samples has nowhere to attach these properties. CORE has them because every admitted claim carries one and the only path to admission is the review path.
**CORE is not "another neuro-symbolic system," and its symbolic character is not GOFAI brittleness.** It does not hand-encode a rule base for a brittle inference engine. Meaning lives in geometric structure — morphology as operator composition, relation as manifold path — and knowledge enters through a reviewed, replayable, epistemically-typed promotion path, never by absorbing a corpus or by an opaque model's say-so.
**The one-line test:** if a description of CORE would apply equally well to a transformer, an embedding store, or a fine-tuned model, that description has miscategorized it. CORE's distinctive claim is that properties which frontier systems implement as *soft, promptable, sampling-level behaviors* are here **architectural invariants that content cannot rewrite** — and that this is what makes a path to trustworthy, auditable autonomy possible at all.
---
## What This Buys You (the same claims, made concrete)
| You might assume… | What CORE actually does |
|---|---|
| "Geometric algebra → it's an equivariant neural net" | No network, no gradients. The Cl(4,1) manifold is the deterministic medium for state, memory, and governance — not a learned feature space. |
| "Inner-product recall → it's a vector DB / ANN" | A Delta-CRDT semilattice: exact, content-addressed, arrival-independent recall that unifies all modalities in one manifold. Exactness is load-bearing, not a scaling liability. |
| "Argmax generation → it's greedy decoding" | A deterministic geometric walk with Forward Semantic Control: inadmissible continuations raise a *typed refusal*, not a forced token. No sampling exists to degenerate. |
| "Refuses a lot → low-coverage abstention" | A deterministic riskreward governor: serving is `wrong=0` by construction; capability compounds in a sealed practice regime; the engine earns coverage by proving reliability. |
| "Identity/persona → a system prompt" | A fixed geometric subspace; override attempts are caught by the geometry of the field-state delta they induce — paraphrase-invariantly, verified against adversarial holdouts. |
| "Learns from data → gradient updates / ingestion" | Reviewed, replay-gated promotion through epistemic tiers. No opaque updates; every extension is auditable and reversible; identity and safety packs are off-limits to self-modification. |
Everything above is enforced in code with a test that fails if the property breaks. Start with the invariant, then the schema, then the evidence:
- **The core invariant:** `pytest tests/test_versor_closure.py`
- **The epistemic substrate:** [`docs/truth_seeking_schema.md`](docs/truth_seeking_schema.md)
- **Reproducible claims (auto-generated, CI-verified):** [`CLAIMS.md`](CLAIMS.md)
- **Architectural vision and formal spec:** [`docs/Whitepaper.md`](docs/Whitepaper.md), [`docs/Yellowpaper.md`](docs/Yellowpaper.md)
All state is a versor. All transitions are versor products.
Coherence is algebraic by construction — not monitored, not corrected.
---
@ -105,18 +57,6 @@ Decision package: [`docs/zig/README.md`](docs/zig/README.md). Adoption gates: [`
---
## The GeometricDelta ABI
To maintain strict physical boundaries, all external signals, modality compiler outputs (e.g. Sopher's Callosum, audio/vision compilers), and cognitive updates entering CORE's Right Hemisphere (RH) must conform to the **`GeometricDelta` ABI**.
- **Physical Closure Invariant**: Every `GeometricDelta` must pass the guarded projector (scalar rescale + monotone Newton iterations) with a residual below configured tolerance ($\epsilon \le 10^{-6}$), or be rejected at the boundary (**reject-and-retain**).
- **Epistemic Invariant**: Every delta carries an epistemic state mapped directly to CORE's truth-seeking schema, defaulting to `SPECULATIVE` until promoted by Vault coherence evidence.
- **Causal Graph (CRDT)**: Deltas are content-addressed and carry causal parents, allowing distributed event-frontier merges instead of simple state mutations.
Core definition: [`core/abi/geometric_delta.py`](core/abi/geometric_delta.py). Validator: [`core/abi/geometric_delta_validator.py`](core/abi/geometric_delta_validator.py).
---
## The Truth-Seeking Schema
Co-equal with the algebraic substrate. CORE's epistemic schema is a foundational architectural commitment: every claim that enters the runtime field carries a typed position in a revision graph (`SPECULATIVE`, `COHERENT`, `CONTESTED`, `FALSIFIED`); coherence — not source authority — is the only admission signal; no claim is ever locked, even when COHERENT; identity cannot be rewritten by content; and exactly one mutation path admits knowledge, enforced by a CI-level architectural-invariant test.

View file

@ -48,36 +48,9 @@ def _build_cga_inner_metric() -> np.ndarray:
_CGA_INNER_METRIC: np.ndarray = _build_cga_inner_metric()
def _f32_1d32(x: np.ndarray) -> np.ndarray:
"""Contiguous f32 (32,) for core_rs PyReadonlyArray1 bindings."""
return np.ascontiguousarray(
np.asarray(x, dtype=np.float32).reshape(-1)[:32], dtype=np.float32
)
def _is_f32_workload(*arrays: np.ndarray) -> bool:
"""True when all arrays are float32 (Rust f32 kernel is parity-safe).
float64 wave residual pins require Python SOT (or future f64 Rust GP).
Forcing f64f32 would break 1e-9 chiral / leakage pins (ADR-0241).
"""
return all(np.asarray(a).dtype == np.float32 for a in arrays)
def geometric_product(A: np.ndarray, B: np.ndarray) -> np.ndarray:
"""Cl(4,1) geometric product via Rust f32 when enabled, else Python.
float64 inputs always use the pure-Python product (semantic SOT for
wave-field residual math). float32 field-graph workloads get Rust.
"""
if _RUST and _is_f32_workload(A, B):
try:
return np.asarray(
_rs.geometric_product(_f32_1d32(A), _f32_1d32(B)),
dtype=np.float32,
)
except (AttributeError, TypeError, ValueError, Exception):
pass
if _RUST:
return np.asarray(_rs.geometric_product(A, B), dtype=np.float32)
from algebra.cl41 import geometric_product as _gp
return _gp(A, B)
@ -94,34 +67,25 @@ def versor_apply(V: np.ndarray, F: np.ndarray) -> np.ndarray:
"""
if _RUST:
try:
Vc = np.ascontiguousarray(V, dtype=np.float64).reshape(-1)[:32]
Fc = np.ascontiguousarray(F, dtype=np.float64).reshape(-1)[:32]
return np.asarray(
_rs.versor_apply_with_closure_f64(Vc, Fc), dtype=np.float64
)
except (AttributeError, TypeError, ValueError, Exception):
Vc = np.ascontiguousarray(V, dtype=np.float64)
Fc = np.ascontiguousarray(F, dtype=np.float64)
return np.asarray(_rs.versor_apply_with_closure_f64(Vc, Fc), dtype=np.float64)
except (AttributeError, Exception):
pass
from algebra.versor import versor_apply as _va
return _va(V, F)
def versor_condition(F: np.ndarray) -> float:
"""Versor residual. Rust f32 path only for float32 inputs (see GP note)."""
if _RUST and _is_f32_workload(F):
try:
return float(_rs.versor_condition(_f32_1d32(F)))
except (AttributeError, TypeError, ValueError, Exception):
pass
if _RUST:
return float(_rs.versor_condition(F))
from algebra.versor import versor_condition as _vc
return _vc(F)
def cga_inner(X: np.ndarray, Y: np.ndarray) -> float:
if _RUST and _is_f32_workload(X, Y):
try:
return float(_rs.cga_inner(_f32_1d32(X), _f32_1d32(Y)))
except (AttributeError, TypeError, ValueError, Exception):
pass
if _RUST:
return float(_rs.cga_inner(X, Y))
from algebra.cga import cga_inner as _ci
return _ci(X, Y)

View file

@ -4,7 +4,7 @@ Conformal Geometric Algebra geometry on Cl(4,1).
Signature: (+,+,+,+,-), with Euclidean coordinates on e1,e2,e3.
The two conformal null directions are built from e4 and e5:
n_o = 0.5 * (e5 - e4) # origin, n_o^2 = 0
n_o = 0.5 * (e4 - e5) # origin, n_o^2 = 0
n_inf = e4 + e5 # infinity, n_inf^2 = 0
n_o · n_inf = -1
@ -39,24 +39,6 @@ _I5[_PSEUDOSCALAR_INDEX] = 1.0
_E4_IDX = 4
_E5_IDX = 5
# The two conformal null directions, frozen as f64 32-vectors — the canonical
# origin/infinity of the CGA point map. These are the SAME vectors ``embed_point``
# builds inline (origin embeds to N_O; N_INF is fixed by every Euclidean isometry),
# hoisted to module constants so the null-point recovery primitives (dilation /
# translation peel) and any incidence code share one exact definition instead of
# re-deriving the signs. Invariants (pinned in tests/test_null_point_primitives.py):
# N_O · N_O = 0, N_INF · N_INF = 0, N_O · N_INF = -1.
# Never mutated; callers that need a scratch copy must ``.copy()``.
N_O = np.zeros(N_COMPONENTS, dtype=np.float64)
N_O[_E4_IDX] = -0.5 # n_o = 0.5 * (e5 - e4)
N_O[_E5_IDX] = 0.5
N_O.setflags(write=False)
N_INF = np.zeros(N_COMPONENTS, dtype=np.float64)
N_INF[_E4_IDX] = 1.0 # n_inf = e4 + e5
N_INF[_E5_IDX] = 1.0
N_INF.setflags(write=False)
# Pinned magnitude ceiling for f64-exact embedding + read-back (Phase 0A).
# Below this bound, ``embed_point(..., dtype=np.float64)`` round-trips integer
# coordinates exactly through ``read_scalar_e1`` and the conformal distance metric

View file

@ -1,275 +0,0 @@
"""Null-point recovery primitives for CGA conformal versors.
Shared substrate for the conformal-Procrustes (#17) and CartanIwasawa (#16)
decompositions. Given a *similarity* versor V (rotation · dilation · translation,
in any order), these peel off the translation it applies to the origin and the
uniform dilation it applies to lengths, using only the exact CGA sandwich
``V·X·rev(V)`` on the two null directions ``N_O`` / ``N_INF`` (see algebra/cga.py:
``n_o = 0.5(e5 - e4)``, ``n_inf = e4 + e5``).
Empirically pinned (f64-exact; probes reproduced in the test module):
* ``V n_inf rev(V) = scale · n_inf`` a similarity FIXES the point at
infinity, so its n_inf image is a *pure* positive multiple of n_inf whose
coefficient is the dilation factor. Anything else a transversion / special
conformal versor leaves an off-n_inf residual and is REFUSED.
* ``V n_o rev(V) = w_o·n_o + scale^-1·a + `` the origin's image is a
conformal point; ``a = euclidean_part / w_o`` recovers the translation by
projective dehomogenization (the weight divides out the dilation, and
rotation fixes the origin, so ``a`` is exact regardless of V's rotation or
scale content the same trick as :func:`algebra.cga.read_scalar_e1`).
Conventions both constructors round-trip through the recoverers:
``dilator(scale)`` scales Euclidean lengths by ``scale`` (> 0);
``recover_dilation(dilator(s)) == s``.
``translator(a)`` maps the origin to Euclidean point ``a`` (3-vector);
``recover_translation(translator(a)) == a``.
Fail-closed discipline (the wrong=0 rule): every recovery raises
:class:`NullPointRecoveryError` on a degenerate, non-versor, or non-similarity
input rather than returning a silently wrong value ``recover_dilation`` and
``recover_translation`` share one versor+similarity gate
(:func:`_require_similarity`), so neither accepts what the other refuses. Guards
are scale-relative so a versor with non-unit weight (e.g. one assembled from a
Kabsch/SVD point cloud) is judged by its *shape*, not its magnitude.
Tolerance: the default ``tol=1e-9`` matches the f64-exact recovery of a cleanly
assembled versor (an SVD-orthogonal rotation composed with an exact
dilator/translator round-trips to ~1e-14). A caller whose versor carries larger
numerical noise e.g. an iteratively refined Procrustes fit must pass a ``tol``
at least as large as that residual, or a valid similarity may be refused as
``not_a_versor`` / ``not_similarity`` (fail-closed: it is never *accepted* with a
wrong value). ``core.physics.conformal_procrustes`` uses ``tol=1e-8`` by convention.
"""
from __future__ import annotations
import numpy as np
from .cga import N_INF, N_O, cga_inner, graded_wedge
from .cl41 import N_COMPONENTS, geometric_product, reverse
# e4 / e5 component indices inside the grade-1 block (mirror of algebra.cga; kept
# local to avoid importing a private name across modules).
_E4_IDX = 4
_E5_IDX = 5
# The dilation bivector E = n_o ^ n_inf. E^2 = +1 (boost-like), so the dilator is
# a hyperbolic exponential cosh + sinh·E. Frozen f64; never mutated.
_E_DILATION = graded_wedge(N_O, N_INF).astype(np.float64)
_E_DILATION.setflags(write=False)
class NullPointRecoveryError(ValueError):
"""A versor is degenerate or not a similarity transform.
Carries a machine-readable ``reason`` for callers that route on the failure
mode (e.g. #17 margin reporting) rather than only surfacing the message.
"""
def __init__(self, message: str, *, reason: str) -> None:
super().__init__(message)
self.reason = reason
def _sandwich(V: np.ndarray, X: np.ndarray) -> np.ndarray:
"""The raw f64 sandwich ``V X rev(V)`` — no closure, no unitisation.
(Deliberately not :func:`algebra.versor.versor_apply`: that path unitises
non-null inputs and coerces to the runtime field dtype. Null-point recovery
needs the exact algebraic image in f64.)
"""
V = np.asarray(V, dtype=np.float64)
X = np.asarray(X, dtype=np.float64)
return geometric_product(geometric_product(V, X), reverse(V))
def dilator(scale: float) -> np.ndarray:
"""Uniform-scale versor that scales Euclidean lengths by ``scale`` (> 0).
``D = exp(0.5·ln(scale)·E) = cosh(h) + sinh(h)·E`` with ``h = 0.5·ln(scale)``
and ``E = n_o ^ n_inf`` (``E^2 = +1``). Acts as
``D n_inf rev(D) = scale·n_inf`` and ``D n_o rev(D) = scale^-1·n_o``.
"""
scale = float(scale)
if not np.isfinite(scale) or scale <= 0.0:
raise NullPointRecoveryError(
f"dilator scale must be finite and positive, got {scale}",
reason="nonpositive_scale",
)
half = 0.5 * np.log(scale)
D = np.zeros(N_COMPONENTS, dtype=np.float64)
D[0] = np.cosh(half)
D = D + np.sinh(half) * _E_DILATION
return D
def translator(a: np.ndarray) -> np.ndarray:
"""Translator versor that maps the origin to Euclidean point ``a`` (3-vector).
``T = 1 - 0.5·a·n_inf`` (a embedded on e1..e3). ``T n_o rev(T)`` equals the
conformal embedding of ``a`` (== :func:`algebra.cga.embed_point`).
"""
a = np.asarray(a, dtype=np.float64)
if a.shape != (3,) or not np.all(np.isfinite(a)):
raise NullPointRecoveryError(
f"translator expects a finite 3-vector, got shape {a.shape}",
reason="bad_translation_vector",
)
a_mv = np.zeros(N_COMPONENTS, dtype=np.float64)
a_mv[1:4] = a
T = np.zeros(N_COMPONENTS, dtype=np.float64)
T[0] = 1.0
T = T - 0.5 * geometric_product(a_mv, N_INF)
return T
def _versor_scalar_weight(V: np.ndarray, tol: float) -> float:
"""Return ``scalar_part(V·rev(V))`` after checking ``V`` is a versor.
A versor satisfies ``V·rev(V) = scalar``; a non-versor multivector leaves an
off-scalar residual. Raises :class:`NullPointRecoveryError` (``not_a_versor``
/ ``degenerate_weight``) otherwise. The weight is what makes
:func:`recover_dilation` weight-invariant the raw ``n_inf`` coefficient
scales with this weight, so the true dilation is the coefficient divided by it.
"""
V = np.asarray(V, dtype=np.float64)
vv = geometric_product(V, reverse(V))
w = float(vv[0])
off_scalar = float(np.linalg.norm(vv[1:]))
ref = max(1.0, abs(w))
if off_scalar > tol * ref:
raise NullPointRecoveryError(
f"V·rev(V) is not scalar (off-scalar residual {off_scalar / ref:.3e}); "
"not a versor",
reason="not_a_versor",
)
if abs(w) <= tol:
raise NullPointRecoveryError(
f"degenerate versor weight {w:.3e}", reason="degenerate_weight",
)
return w
def _require_similarity(V: np.ndarray, tol: float) -> tuple[float, float]:
"""Gate ``V`` as a similarity versor; return ``(weight, signed_scale)``.
A similarity (rotation · dilation · translation, in any order) is the only
class both recoverers accept: it is a versor (``V·rev(V)`` scalar) *and* it
fixes infinity (``V n_inf rev(V)`` is a pure multiple of ``n_inf``). The
returned ``signed_scale = c_inf / weight`` is positive for a proper similarity
and negative for an orientation-reversing (improper / reflection) one; sign
and degeneracy classification is left to the caller, so
:func:`recover_translation` can accept a reflection whose origin image is
still well defined while :func:`recover_dilation` refuses it.
Raises :class:`NullPointRecoveryError` with ``not_a_versor`` /
``degenerate_weight`` (from :func:`_versor_scalar_weight`) or ``not_similarity``.
"""
weight = _versor_scalar_weight(V, tol)
W = _sandwich(V, N_INF)
c_inf = 0.5 * (float(W[_E4_IDX]) + float(W[_E5_IDX]))
resid = W.copy()
resid[_E4_IDX] -= c_inf
resid[_E5_IDX] -= c_inf
resid_norm = float(np.linalg.norm(resid))
ref = max(1.0, float(np.linalg.norm(W)))
if resid_norm > tol * ref:
raise NullPointRecoveryError(
f"versor does not fix infinity (off-n_inf residual "
f"{resid_norm / ref:.3e} > {tol:.1e}); not a similarity transform",
reason="not_similarity",
)
return weight, c_inf / weight
def recover_dilation(V: np.ndarray, *, tol: float = 1e-9) -> tuple[float, np.ndarray]:
"""Recover the uniform scale a similarity versor ``V`` applies to lengths.
Returns ``(scale, D)`` with ``D == dilator(scale)`` and ``scale > 0``. Reads
the image of the point at infinity ``W = V n_inf rev(V)`` (for a similarity a
pure multiple of ``n_inf``) and normalises its coefficient by the versor weight
``V·rev(V)`` the sandwich scales with that weight, so a non-unit versor still
yields the true scale (verified against ``V -> kV``).
Raises :class:`NullPointRecoveryError` when
* ``V`` is not a versor (``not_a_versor`` / ``degenerate_weight``) or does
not fix infinity, i.e. is not a similarity (``not_similarity`` e.g. a
transversion);
* ``V`` is orientation-reversing a reflection / improper rotation, the
``det = -1`` case a raw Kabsch/SVD fit produces before it strips the
reflection (``core.physics.conformal_procrustes`` does strip it). Its
signed scale is a clean negative, refused as ``improper_versor``, kept
distinct from true degeneracy so a caller can tell "flip a singular
vector" from "numerically broken". :func:`recover_translation` still
accepts such a versor only the *dilation* is ill-defined for an improper
map here; or
* the recovered scale is non-finite or collapses to zero (``degenerate_scale``).
"""
_, scale = _require_similarity(V, tol)
# Preserve the original accept-set exactly (finite *positive* scale, any
# magnitude); split the negative case out to a distinct, honest reason.
if not np.isfinite(scale):
raise NullPointRecoveryError(
f"degenerate dilation coefficient {scale}",
reason="degenerate_scale",
)
if scale < 0.0:
raise NullPointRecoveryError(
f"orientation-reversing versor (signed scale {scale:.6g}); an improper "
"similarity has no positive dilation — strip the reflection first",
reason="improper_versor",
)
if scale == 0.0:
raise NullPointRecoveryError(
"degenerate dilation coefficient 0.0 (versor collapses n_inf)",
reason="degenerate_scale",
)
return scale, dilator(scale)
def recover_translation(V: np.ndarray, *, tol: float = 1e-9) -> tuple[np.ndarray, np.ndarray]:
"""Recover the translation a similarity versor ``V`` applies to the origin.
Returns ``(a, T)`` with ``a`` the Euclidean image of the origin (3-vector)
and ``T == translator(a)``. Reads ``W = V n_o rev(V)`` and dehomogenizes
projectively: ``a = W[e1:e3+1] / w_o`` where ``w_o = W[e5] - W[e4]``. The
weight divides out any dilation, and rotation proper *or* a reflection
fixes the origin, so ``a`` is exact regardless of ``V``'s rotation/scale
content. An improper (reflection) similarity is therefore accepted here even
though :func:`recover_dilation` refuses it: the origin image is well defined,
only the positive dilation is not.
Gates ``V`` as a similarity versor first (the same :func:`_require_similarity`
gate as :func:`recover_dilation`), so a non-versor or a non-similarity e.g. a
transversion, which fixes the origin and would otherwise return a plausible
``a`` silently fails closed rather than returning a wrong value.
Raises :class:`NullPointRecoveryError` when
* ``V`` is not a versor (``not_a_versor`` / ``degenerate_weight``) or does
not fix infinity (``not_similarity``);
* the origin maps to infinity (``origin_at_infinity`` ``|w_o|`` at/below
``tol``; guards the projective division, subsumed by the similarity gate
for genuine inversions); or
* the origin image leaves the null cone (``non_null_image`` scale-relative
defect > ``tol``), so ``W`` is not a conformal point.
"""
_require_similarity(V, tol)
W = _sandwich(V, N_O)
w_o = float(W[_E5_IDX] - W[_E4_IDX])
if abs(w_o) <= tol:
raise NullPointRecoveryError(
f"origin maps to infinity (n_o weight {w_o:.3e}); no finite translation",
reason="origin_at_infinity",
)
null_defect = abs(cga_inner(W, W))
ref = max(1.0, float(np.dot(W, W)))
if null_defect > tol * ref:
raise NullPointRecoveryError(
f"origin image leaves the null cone (defect {null_defect / ref:.3e}); "
"not a conformal point",
reason="non_null_image",
)
a = np.asarray(W[1:4], dtype=np.float64) / w_o
return a, translator(a)

View file

@ -8,23 +8,13 @@ it describes a transformation being applied, not a property of the vocabulary.
import numpy as np
from .cl41 import N_COMPONENTS, geometric_product, grade_project, reverse, scalar_part
from .cl41 import N_COMPONENTS, geometric_product, reverse
from .versor import unitize_versor, versor_condition
_TRANSITION_CONDITION_TOL = 1e-4
_NEAR_ZERO_TOL = 1e-12
_SAME_POINT_TOL = 1e-6
_STRICT_RESIDUE_TOL = 1e-2
# A rotor is SIMPLE iff its grade-4 part vanishes (<R>_4 == 0 <=> R = R1 with a
# single invariant plane). Above this, the rotor needs the invariant split.
_SIMPLE_GRADE4_TOL = 1e-10
# After the invariant (bivector) split, each factor is *approximately* simple;
# B² higher-grade residual is float dust, not a true multi-plane bivector.
# 1e-6 was too tight (raised on live word-transition / stream weights ≈ 1e-6..1e-3).
# Refuse only residuals that are clearly structural non-simplicity.
_SIMPLE_BSQ_HIGHER_TOL = 1e-3
# |discriminant| below this => the two invariant eigenvalues coincide (isoclinic).
_DEGEN_TOL = 1e-9
def _identity(dtype: np.dtype) -> np.ndarray:
@ -85,71 +75,40 @@ def make_rotor_from_angle(angle: float, bivector_idx: int = 6) -> np.ndarray:
def rotor_power(R: np.ndarray, alpha: float) -> np.ndarray:
"""Return R^alpha — the rotor on the manifold path from identity to R by alpha.
EXACT for ANY closed unit rotor in Cl(4,1), simple or not. A general rotor
factors (invariant / bivector decomposition) into two commuting SIMPLE
rotors ``R = R1 R2`` with distinct invariant planes; then, because they
commute, ``R^α = R1^α R2^α`` and each factor uses the simple closed form
below. The isoclinic case (coincident invariant planes) has its own closed
form. There is no iteration, no approximation, and no external library
the split is built from the Cl(4,1) geometric product alone.
Simple factor ``R_i = a + B`` (scalar + simple bivector):
For a simple unit rotor decomposed as ``R = a + B`` (scalar + bivector):
- rotation plane (`` < 0``): ``R^α = cos(α·θ/2) + (sin(α·θ/2)/|B|) · B``
where ``θ/2 = atan2(|B|, a)``.
- boost plane (`` > 0``): ``R^α = cosh(α·η/2) + (sinh(α·η/2)/|B|) · B``
where ``η/2 = atanh(|B|/a)``.
The result stays on the rotor manifold by construction, so
``versor_condition(rotor_power(R, α)) < 1e-6`` for any α whenever ``R`` is a
closed unit rotor. (Historically this returned the *identity* for non-simple
rotors an approximation where exactness was available, which silently
collapsed geodesic interpolation to a no-op. That corner is now closed.)
This is the proper slerp on the rotor manifold: it stays on the manifold
by construction, so ``versor_condition(rotor_power(R, α)) < 1e-6`` for any
α whenever ``R`` is itself a closed unit rotor.
Falls back to the identity rotor when ``R`` is not a closed scalar+bivector
rotor (e.g. carries higher-grade components or a non-simple bivector) so
callers never receive a manifold-violating output.
"""
R_arr = np.asarray(R, dtype=np.float64)
if R_arr.shape != (N_COMPONENTS,):
raise ValueError(
f"rotor_power expects a {N_COMPONENTS}-component rotor; got {R_arr.shape}."
)
dtype = _result_dtype(R_arr)
a = float(alpha)
# Endpoints by continuity: R^0 = 1, R^1 = R. Stream weights can be denormal
# tiny; never run the invariant split on α≈0 (smoke / generate.stream path).
if abs(a) <= _NEAR_ZERO_TOL:
return _identity(dtype)
if abs(a - 1.0) <= _NEAR_ZERO_TOL:
return R_arr.astype(dtype, copy=True)
# <R>_4 == 0 <=> R is a single simple rotor. Otherwise take the split path.
if float(np.linalg.norm(grade_project(R_arr, 4))) >= _SIMPLE_GRADE4_TOL:
return _general_rotor_power(R_arr, a, dtype)
return _simple_rotor_power(R_arr, a, dtype)
def _simple_rotor_power(R_arr: np.ndarray, alpha: float, dtype: np.dtype) -> np.ndarray:
"""R^alpha for a SIMPLE rotor (scalar + one simple bivector). Exact closed form.
Behaviour is unchanged from the original ``rotor_power`` on simple inputs.
"""
a = float(R_arr[0])
B = R_arr.copy()
B[0] = 0.0
# A simple rotor's bivector squares to a scalar (B² is grade-0 only).
# Higher-grade residual above _SIMPLE_BSQ_HIGHER_TOL is structural non-simplicity
# (fail closed). Below that, treat as float dust from the invariant split and
# use only the scalar part of B² (closed form still exact on the simple plane).
# Quick guard: bivector must be a simple bivector (B² is grade-0 only).
B_sq_full = geometric_product(B, B).astype(np.float64)
bsq_scalar = float(B_sq_full[0])
B_sq_higher = B_sq_full.copy()
B_sq_higher[0] = 0.0
higher_norm = float(np.linalg.norm(B_sq_higher))
if higher_norm > _SIMPLE_BSQ_HIGHER_TOL:
# Not a simple bivector under the simple dispatch — fail closed, never
# silently return identity (that zeros motion without a signal).
raise ValueError(
"rotor_power: non-simple bivector under simple dispatch "
f"(B² higher-grade residual {higher_norm:.3e})"
)
if float(np.linalg.norm(B_sq_higher)) > 1e-6:
# Non-simple bivector — return identity to avoid drift.
return _identity(dtype)
# Near-identity: nothing to scale.
bivector_norm = float(np.linalg.norm(B))
@ -164,30 +123,19 @@ def _simple_rotor_power(R_arr: np.ndarray, alpha: float, dtype: np.dtype) -> np.
new_a = float(np.cos(alpha * theta_half))
new_b_mag = float(np.sin(alpha * theta_half))
elif bsq_scalar > 0.0:
# Boost plane. Domain of atanh requires |b_mag/a| < 1 and a > 0.
# Boost plane.
b_mag = float(np.sqrt(bsq_scalar))
if a <= 0.0 or abs(b_mag / a) >= 1.0 - 1e-12:
raise ValueError(
f"rotor_power: boost plane outside unit-rotor domain "
f"(a={a:.6g}, |B|/a={abs(b_mag / a) if a != 0.0 else float('inf'):.6g})"
)
# atanh requires |b_mag/a| < 1; for closed rotors a² - B² = 1 means
# |b_mag| < |a|, so this is safe when a > 0.
if a == 0.0:
return _identity(dtype)
eta_half = float(np.arctanh(b_mag / a))
new_a = float(np.cosh(alpha * eta_half))
new_b_mag = float(np.sinh(alpha * eta_half))
else:
# B² = 0: null bivector (translator generators in CGA). Exact binomial:
# (a + B)^α = a^α + α a^{α-1} B (higher powers of B vanish).
# Unit translators have a = 1 ⇒ T^α = 1 + α B = translator(α·a_eucl).
# Historically this returned identity — a silent zeroing of the Cartan
# translation leg in dual_correction_slerp (fidelity #16 follow-up).
if abs(a) < _NEAR_ZERO_TOL:
return _identity(dtype)
result = np.zeros(N_COMPONENTS, dtype=np.float64)
result[0] = float(a) ** float(alpha) if a > 0.0 else float(np.sign(a) * (abs(a) ** float(alpha)))
# Prefer real power for a>0; for a<0 (rare for unit translators) use |a|^α · sgn.
scale_B = float(alpha) * (float(a) ** (float(alpha) - 1.0)) if a > 0.0 else float(alpha) * (abs(a) ** (float(alpha) - 1.0)) * float(np.sign(a))
result = result + scale_B * B
return result.astype(dtype, copy=False)
# B² = 0: null bivector. Cannot interpolate on the manifold;
# return identity to fail safely.
return _identity(dtype)
result = np.zeros(N_COMPONENTS, dtype=np.float64)
result[0] = new_a
@ -196,92 +144,6 @@ def _simple_rotor_power(R_arr: np.ndarray, alpha: float, dtype: np.dtype) -> np.
return result.astype(dtype, copy=False)
def _isoclinic_power_coeffs(x: float, alpha: float) -> tuple[float, float, float]:
"""Power coefficients ``(A, f, c)`` for one of two identical (isoclinic) simple
factors with `` = x``: ``R_i^α = A + f · G_i``. Handles rotation, boost, and
the null limit uniformly.
"""
gsq = x - 1.0
c = float(np.sqrt(max(x, 0.0)))
if gsq < -1e-15: # rotation: c = cos(theta)
theta = float(np.arccos(min(1.0, max(-1.0, c))))
slin = float(np.sin(theta))
A = float(np.cos(alpha * theta))
f = float(np.sin(alpha * theta) / slin) if slin > 1e-300 else float(alpha)
elif gsq > 1e-15: # boost: c = cosh(eta)
eta = float(np.arccosh(max(1.0, c)))
slin = float(np.sinh(eta))
A = float(np.cosh(alpha * eta))
f = float(np.sinh(alpha * eta) / slin) if slin > 1e-300 else float(alpha)
else: # null / parabolic limit
A, f = 1.0, float(alpha)
return A, f, c
def _split_commuting_simple(
P: float, H: np.ndarray, W: np.ndarray, h0: float, disc: float
) -> tuple[np.ndarray, np.ndarray]:
"""Invariant decomposition of a non-simple rotor into two commuting SIMPLE
unit rotors ``R = R1 R2`` (distinct-eigenvalue branch).
With ``P = <R>_0``, ``H = <R>_2``, ``W = <R>_4``: the squared scalars of the
two simple factors are ``x_i = c_i²`` the roots of `` (2h0) t + ``
and each simple bivector ``G_i`` is recovered by the linear system in
``{H, HW}``. Returns ``(R1, R2)`` as 32-component rotors.
"""
b = 2.0 * P * P - h0
sq = float(np.sqrt(disc))
x1 = 0.5 * (b + sq)
x2 = 0.5 * (b - sq)
c1 = float(np.sqrt(max(x1, 0.0)))
c2 = float(np.sqrt(max(x2, 0.0)))
if P < 0.0:
c2 = -c2 # fix product sign so c1·c2 == <R>_0
g1sq = x1 - 1.0
g2sq = x2 - 1.0
HW = grade_project(geometric_product(H, W), 2).astype(np.float64)
det = c2 * c2 * g1sq - c1 * c1 * g2sq
if abs(det) < _NEAR_ZERO_TOL:
raise ValueError(
"rotor_power: singular invariant split (unexpected for distinct eigenvalues)"
)
G1 = (c2 * g1sq * H - c1 * HW) / det
G2 = (c2 * HW - c1 * g2sq * H) / det
R1 = G1.copy()
R1[0] = c1
R2 = G2.copy()
R2[0] = c2
return R1, R2
def _general_rotor_power(R_arr: np.ndarray, alpha: float, dtype: np.dtype) -> np.ndarray:
"""R^alpha for a NON-simple rotor via the invariant (bivector) decomposition."""
P = float(R_arr[0])
H = grade_project(R_arr, 2).astype(np.float64)
W = grade_project(R_arr, 4).astype(np.float64)
h0 = float(scalar_part(geometric_product(H, H)))
b = 2.0 * P * P - h0
disc = b * b - 4.0 * P * P
if disc <= _DEGEN_TOL:
# Isoclinic: coincident invariant planes (x1 == x2 == b/2). The result
# depends only on the symmetric functions H and W, so no per-plane split
# is needed: R^α = A² + (A·f/c)·H + f²·W.
A, f, c = _isoclinic_power_coeffs(0.5 * b, alpha)
if c < _NEAR_ZERO_TOL:
raise ValueError(
"rotor_power: isoclinic rotor at theta~pi/2 has no principal power"
)
out = (A * f / c) * H + (f * f) * W
out[0] += A * A
return out.astype(dtype, copy=False)
R1, R2 = _split_commuting_simple(P, H, W, h0, disc)
out = geometric_product(
_simple_rotor_power(R1, alpha, np.dtype(np.float64)),
_simple_rotor_power(R2, alpha, np.dtype(np.float64)),
)
return out.astype(dtype, copy=False)
def word_transition_rotor(A: np.ndarray, B: np.ndarray) -> np.ndarray:
"""
Compute the closed transition operator from source versor A to target B.

View file

@ -1,82 +0,0 @@
# Topological Reasoning — ADR-0242 Vector 5 (D6) Research Quarantine
**Status**: 🔴 RESEARCH ONLY — blocked from production
**Authority**: ADR-0242 Vector 5 (topological anyon / braid holonomy)
**Related**: `docs/adr/ADR-0242-atlas-packing-and-fibonacci.md`,
`docs/analysis/fibonacci_applications_in_core_substrate.md` §2.2
---
## Purpose
Isolated study surface for Fibonacci anyon fusion and braid holonomy as a
**topological composition research program**. The canonical fusion rule under
study is:
\[
\tau \otimes \tau = \mathbf{1} \oplus \tau
\]
This package exists so research stubs, notes, and future proof-carrying
algebra can land **without** contaminating the live cognitive path:
```text
listen → comprehend → recall → think → articulate → learn → replay
```
## Hard quarantine (do not violate)
Until algebraic **and** numerical proofs exist, and until an explicit ADR
promotion gate is Accepted by human review, this package is **BLOCKED** from:
| Surface | Rule |
|---------|------|
| Production runtime | No imports from serve / hot path |
| `chat/` | Not for import by chat or `chat/runtime.py` |
| Serve / FFI | Must not enter serve or FFI bindings |
| `core/physics/` | Not a production physics operator |
| `generate/` | Not for articulation / planner / cognitive turns |
| `vault/` | Not for vault standing, seal, or COHERENT promotion |
| `teaching/` | Not for reviewed teaching or pack mutation |
| GoldTether / κ paths | Not for production residual / κ optimization |
| `algebra` public surface | Not re-exported from `algebra/__init__.py` |
Architectural pin: `tests/test_adr_0242_topological_quarantine.py` scans
production packages for any import of `topological_reasoning` and must find
none.
## Sovereignty (ADR-0242)
Fibonacci / topological operators may **never** dictate proposition truth,
safety policy, identity, or authorize autonomous COHERENT promotion. Active
reasoning remains governed by versor closure, exact CRDT recall, and
human-gated review.
## What is allowed here
- Research constants and docstring contracts (e.g. fusion rule labels)
- Future proof sketches, numerical experiments under tests/evals only when
explicitly gated
- Documentation of open questions and proof obligations
## What is not allowed here
- Production logic wired into cognition, serve, or vault truth
- Stochastic / approximate substitutes for exact CGA recall
- Hidden normalization or drift repair outside owned algebra boundaries
- Silent promotion of research results into COHERENT standing
## API note
The package may expose minimal docstring / constant stubs (e.g. `FUSION_RULE`).
No production operators, no side effects, no I/O.
## Promotion path
1. Algebraic + numerical proofs land and are reviewable.
2. ADR update records evidence and remaining risks.
3. Human Accept of a production promotion gate.
4. Only then may a **separate**, reviewed integration surface be designed —
still subject to serve quarantine and sovereignty invariant.
Until then: this directory is a quarantine box, not a feature.

View file

@ -1,21 +0,0 @@
"""ADR-0242 V5 (D6) — topological anyon / braid holonomy research quarantine.
Fibonacci anyon fusion research surface. BLOCKED from production, serve, FFI,
chat/runtime, vault COHERENT, teaching mutation, and GoldTether production
paths until algebraic and numerical proofs exist (see package README).
This module intentionally re-exports nothing into ``algebra``'s public API
and must not be imported by production packages.
"""
from __future__ import annotations
# Canonical Fibonacci anyon fusion rule under study (research label only).
# τ ⊗ τ = 1 ⊕ τ — not a production operator; no evaluation semantics.
FUSION_RULE: str = "tau_otimes_tau_eq_1_oplus_tau"
"""Research label for the Fibonacci anyon fusion rule τ⊗τ = 1⊕τ.
Docstring / constant only. Does not implement fusion, braiding, or holonomy.
"""
__all__ = ["FUSION_RULE"]

View file

@ -17,9 +17,9 @@ from __future__ import annotations
import json
from pathlib import Path
from packs.schema import AlignmentEdge
from language_packs.schema import AlignmentEdge
_DATA_DIR = Path(__file__).parent.parent / "packs" / "data"
_DATA_DIR = Path(__file__).parent.parent / "language_packs" / "data"
class AlignmentGraph:
@ -74,7 +74,7 @@ def load_alignment(
"""
Load AlignmentEdge records from <data_root>/<pack_id>/alignment.jsonl.
``data_root`` defaults to the committed ``packs/data`` tree; pass
``data_root`` defaults to the committed ``language_packs/data`` tree; pass
an alternate root (e.g. a test-fixture copy) to read packs from elsewhere
without forking the parser.

View file

@ -288,7 +288,7 @@ def run_footprint(*, pack_id: str = "en_core_cognition_v1") -> FootprintReport:
rss_post = _rss_bytes()
py_bytes, py_modules = _measure_python_runtime()
pack_path = PROJECT_ROOT / "packs" / "data" / pack_id
pack_path = PROJECT_ROOT / "language_packs" / "data" / pack_id
vault_path = PROJECT_ROOT / "vault"
rust_path = _rust_artifact_path()
seed_packs_path = PROJECT_ROOT / "packs"

View file

@ -152,7 +152,7 @@ def bench_backend_speedup() -> BenchResult:
will be tracked when the doctrine clock advances.
"""
from field.operators import GraphDiffusionOperator
from packs.compiler import load_pack
from language_packs.compiler import load_pack
from scripts.run_pulse import _build_manifold
_, manifold = load_pack("en_core_cognition_v1")
@ -225,7 +225,7 @@ def bench_versor_closure_audit() -> BenchResult:
"""Run pulse for all eval cases, verify versor_condition < 1e-6 at every step."""
from algebra.backend import versor_condition
from field.operators import GraphDiffusionOperator, ConstraintCorrectionOperator
from packs.compiler import load_pack
from language_packs.compiler import load_pack
from scripts.run_pulse import _build_manifold
_, manifold = load_pack("en_core_cognition_v1")

View file

@ -60,7 +60,7 @@ _ANCHOR_LENS_SUBSTRATE_PACK_IDS: dict[str, tuple[str, ...]] = {
_PACK_LEXICON_PATH = (
Path(__file__).resolve().parent.parent
/ "packs"
/ "language_packs"
/ "data"
/ PACK_ID
/ "lexicon.jsonl"
@ -76,7 +76,7 @@ _PACK_LEXICON_PATH = (
# lemmas — only lens-engagement reads from here.
_COLLAPSE_ANCHORS_LEXICON_PATH = (
Path(__file__).resolve().parent.parent
/ "packs"
/ "language_packs"
/ "data"
/ "en_collapse_anchors_v1"
/ "lexicon.jsonl"
@ -130,7 +130,7 @@ def _frame_gloss(lemma: str, pos: str, gloss: str) -> str:
* (unknown) -> "{Lemma}: {gloss}." (back-compat fallback)
The glosses are authored to match these frames exactly (see
the subagent briefs and ``packs/data/<pack>/glosses.jsonl``).
the subagent briefs and ``language_packs/data/<pack>/glosses.jsonl``).
Capitalization is applied only to the framed surface, never to
the lemma in the lexicon (which stays lowercase by convention).
"""
@ -253,7 +253,7 @@ def _substrate_lexicon_by_entry_id(pack_id: str) -> dict[str, tuple[str, ...]]:
"""
lexicon_path = (
Path(__file__).resolve().parent.parent
/ "packs"
/ "language_packs"
/ "data"
/ pack_id
/ "lexicon.jsonl"

View file

@ -32,10 +32,8 @@ Design constraints (CLAUDE.md / Reconstruction-over-storage):
from __future__ import annotations
import json
from dataclasses import dataclass
from functools import lru_cache
from pathlib import Path
from typing import Sequence
# Default mounted lexicon-pack ids that ADR-0063 surface composers
# consult. Order matters: earlier packs win on lemma collision. This
@ -71,47 +69,7 @@ DEFAULT_RESOLVABLE_PACK_IDS: tuple[str, ...] = (
"en_collapse_anchors_v1",
)
# 3-core-language (English + Hebrew root density + Koine Greek Logos precision)
# depth packs for LexicalResolution. These are used alongside DEFAULT when
# building PropositionGraph nodes with language/root/morphology_id for
# bidirectional comprehension/articulation/contemplation.
# Sourced to align with anchor-lens substrate packs.
DEPTH_PACK_IDS: tuple[str, ...] = (
"he_core_cognition_v1",
"he_logos_micro_v1",
"grc_logos_cognition_v1",
"grc_logos_micro_v1",
)
@dataclass(frozen=True, slots=True)
class LexicalResolution:
"""Immutable, shared lexical resolution for masterful bidirectional use.
Serves comprehension (ingest grounded PropositionGraph via resolve_gloss
path), articulation (graph realize_semantic can consult depth for
precision), and internal reasoning/contemplation (operations "between"
read/write on the same substrate).
Three core languages:
- English: operational base
- Hebrew: root density (e.g. ד-ב-ר for utterance/word)
- Koine Greek: Logos precision (structuring principle, John 1:1)
The geometric field and PropositionGraph are designed to hold this depth.
All fields are plain values; no mutation.
"""
pack_id: str
lemma: str
language: str
pos: str = ""
gloss: str | None = None
semantic_domains: tuple[str, ...] = ()
morphology_id: str | None = None
root: str | None = None
_PACK_ROOT = Path(__file__).resolve().parent.parent / "packs" / "data"
_PACK_ROOT = Path(__file__).resolve().parent.parent / "language_packs" / "data"
@lru_cache(maxsize=16)
@ -278,157 +236,6 @@ def resolve_gloss(
return None
@lru_cache(maxsize=16)
def _pack_full_lexicon_for(pack_id: str) -> dict[str, dict]:
"""Return richer {lemma_lower: entry} including language, morphology_id,
semantic_domains for 3-language depth resolution.
Mirrors _pack_lexicon_for structure but retains the full fields needed
for LexicalResolution (Hebrew/Greek root-linked entries etc.).
Immutable packs safe to cache.
"""
lexicon_path = _PACK_ROOT / pack_id / "lexicon.jsonl"
if not lexicon_path.exists():
return {}
out: dict[str, dict] = {}
for line in lexicon_path.read_text(encoding="utf-8").splitlines():
line = line.strip()
if not line:
continue
try:
entry = json.loads(line)
except json.JSONDecodeError:
continue
if not isinstance(entry, dict):
continue
lemma = entry.get("lemma") or entry.get("surface")
if not lemma or not isinstance(lemma, str):
continue
key = lemma.strip().lower()
# retain relevant depth fields
out[key] = {
"language": entry.get("language") or "en",
"morphology_id": entry.get("morphology_id"),
"semantic_domains": tuple(str(d) for d in entry.get("semantic_domains", ())),
"pos": entry.get("pos") or "",
}
return out
@lru_cache(maxsize=16)
def _pack_morph_roots_for(pack_id: str) -> dict[str, str]:
"""Return {morphology_id: root} for the pack's morphology.jsonl.
Enables root-level depth (Hebrew triconsonantal, Greek stems) without
pulling the full MorphologyRegistry into the hot resolver path.
"""
morph_path = _PACK_ROOT / pack_id / "morphology.jsonl"
if not morph_path.exists():
return {}
out: dict[str, str] = {}
for line in morph_path.read_text(encoding="utf-8").splitlines():
line = line.strip()
if not line:
continue
try:
entry = json.loads(line)
except json.JSONDecodeError:
continue
if not isinstance(entry, dict):
continue
mid = entry.get("morphology_id")
root = entry.get("root")
if isinstance(mid, str) and isinstance(root, str) and mid and root:
out[mid] = root
return out
def resolve_entry(
lemma: str,
pack_ids: tuple[str, ...] = DEFAULT_RESOLVABLE_PACK_IDS,
) -> LexicalResolution | None:
"""Return rich LexicalResolution for the first matching pack.
This is the canonical entry point for depth-aware resolution usable
both for comprehension grounding and (symmetrically) articulation /
contemplation. Falls back gracefully for English-centric packs.
First-match-wins, same order as resolve_lemma/resolve_gloss.
"""
if not lemma or not isinstance(lemma, str):
return None
key = lemma.strip().lower()
if not key:
return None
for pack_id in pack_ids:
full = _pack_full_lexicon_for(pack_id)
if key not in full:
continue
info = full[key]
# gloss is optional but preferred when present
glosses = _pack_glosses_for(pack_id)
pos, gloss = glosses.get(key, ("", None))
if not gloss:
# fall back to pos from full if no dedicated gloss
pos = info.get("pos", "") or pos
morph_id = info.get("morphology_id")
root = None
if morph_id:
roots = _pack_morph_roots_for(pack_id)
root = roots.get(morph_id)
return LexicalResolution(
pack_id=pack_id,
lemma=lemma,
language=info.get("language", "en"),
pos=pos or "",
gloss=gloss,
semantic_domains=info.get("semantic_domains", ()),
morphology_id=morph_id,
root=root,
)
return None
def resolve_token_depths(
tokens: Sequence[str],
pack_ids: tuple[str, ...] | None = None,
) -> tuple[dict[str, dict], str | None]:
"""Resolve he/grc depth for raw tokens before PropositionGraph exists.
Same-turn recognition needs root data before graph build fills
``node_depths`` with ``p*`` ids. This returns provisional depths keyed
by ``t{i}`` (token index) for tokens that resolve with he/grc language
and a root, plus the first such provisional node id as the agent
candidate.
Pure relative to pack lexicon lookups (deterministic exact match).
Empty when no depth-bearing tokens are present.
"""
if pack_ids is None:
pack_ids = DEFAULT_RESOLVABLE_PACK_IDS + DEPTH_PACK_IDS
depths: dict[str, dict] = {}
agent_node_id: str | None = None
if not tokens:
return depths, agent_node_id
for i, tok in enumerate(tokens):
if not isinstance(tok, str) or not tok.strip():
continue
res = resolve_entry(tok, pack_ids=pack_ids)
if res is None:
continue
lang = res.language
root = res.root
if lang not in ("he", "grc") or not root:
continue
nid = f"t{i}"
entry: dict = {"language": lang, "root": root}
if res.morphology_id:
entry["morphology_id"] = res.morphology_id
depths[nid] = entry
if agent_node_id is None:
agent_node_id = nid
return depths, agent_node_id
def clear_resolver_cache() -> None:
"""Drop all caches in this module — lexicon AND glosses.
@ -444,99 +251,3 @@ def clear_resolver_cache() -> None:
"""
_pack_lexicon_for.cache_clear()
_pack_glosses_for.cache_clear()
_pack_lemma_to_entry_id.cache_clear()
_pack_senses_for.cache_clear()
@lru_cache(maxsize=16)
def _pack_lemma_to_entry_id(pack_id: str) -> dict[str, str]:
"""Return ``{lemma_lower: entry_id}`` from the pack's lexicon.jsonl."""
lexicon_path = _PACK_ROOT / pack_id / "lexicon.jsonl"
if not lexicon_path.exists():
return {}
out: dict[str, str] = {}
for line in lexicon_path.read_text(encoding="utf-8").splitlines():
line = line.strip()
if not line:
continue
try:
entry = json.loads(line)
except json.JSONDecodeError:
continue
if not isinstance(entry, dict):
continue
lemma = entry.get("lemma") or entry.get("surface")
if not lemma or not isinstance(lemma, str):
continue
entry_id = entry.get("entry_id")
if isinstance(entry_id, str) and entry_id.strip():
out[lemma.lower()] = entry_id.strip()
return out
@lru_cache(maxsize=16)
def _pack_senses_for(pack_id: str) -> dict[str, dict]:
"""Return ``{lemma_id: geometric_signature}`` from the pack's optional
``senses.jsonl`` file. Also maps ``lemma`` as a fallback key.
"""
path = _PACK_ROOT / pack_id / "senses.jsonl"
if not path.exists():
return {}
out: dict[str, dict] = {}
for line in path.read_text(encoding="utf-8").splitlines():
line = line.strip()
if not line:
continue
try:
entry = json.loads(line)
except json.JSONDecodeError:
continue
if not isinstance(entry, dict):
continue
geometric_signature = entry.get("geometric_signature")
if not isinstance(geometric_signature, dict):
continue
lemma_id = entry.get("lemma_id")
if isinstance(lemma_id, str) and lemma_id.strip():
out[lemma_id.strip()] = geometric_signature
# Optional fallback for direct lemma matching if lemma is present
lemma = entry.get("lemma")
if isinstance(lemma, str) and lemma.strip():
out[lemma.strip().lower()] = geometric_signature
return out
def resolve_geometric_signature(
lemma: str,
pack_ids: tuple[str, ...] = DEFAULT_RESOLVABLE_PACK_IDS,
) -> tuple[str, dict] | None:
"""Return ``(pack_id, geometric_signature)`` for the first pack in
*pack_ids* that BOTH (a) ratifies *lemma* in its ``lexicon.jsonl``
AND (b) carries a geometric_signature for it in ``senses.jsonl``.
"""
if not lemma or not isinstance(lemma, str):
return None
key = lemma.strip().lower()
if not key:
return None
for pack_id in pack_ids:
lex = _pack_lexicon_for(pack_id)
if key not in lex:
continue
lemma_ids = _pack_lemma_to_entry_id(pack_id)
entry_id = lemma_ids.get(key)
senses = _pack_senses_for(pack_id)
if entry_id and entry_id in senses:
return (pack_id, senses[entry_id])
if key in senses:
return (pack_id, senses[key])
return None

View file

@ -107,7 +107,7 @@ from generate.result import GenerationResult
from generate.stream import generate
from generate.surface import SentenceAssembler, SentencePlan, SurfaceContext
from ingest.gate import inject
from packs import OOVPolicy, load_mounted_packs, load_pack, load_pack_entries
from language_packs import OOVPolicy, load_mounted_packs, load_pack, load_pack_entries
from persona.motor import PersonaMotor
from session.context import SessionContext
from session.correction import CorrectionPass
@ -608,7 +608,6 @@ class ChatRuntime:
pack_ids = tuple(config.input_packs)
self.config = resolved_config
self._last_node_depths: dict | None = None # 3-lang PropGraph depth propagation (he/grc roots) to contemplate paths; set by pipeline
manifests = []
manifolds = []
entries = []
@ -888,18 +887,10 @@ class ChatRuntime:
self._pending_recognizer_examples.clear()
candidates_to_save = self._pending_candidates
if self.config.auto_contemplate and candidates_to_save:
# 3-lang depth propagation contract (AC5 / review):
# _last_node_depths is written by CognitiveTurnPipeline after PropGraph construction
# (from resolver + build_node_depths on enriched GraphNodes). It is forwarded here
# as depth= into teaching.contemplation.contemplate so that framing findings and
# proposed_chain carry depth_roots for he/grc. Same contract used for runtime
# contemplate and candidate paths. See also core/cognition/result.py (node_depths /
# graph_anti_unify on result) + pipeline.py.
from teaching.contemplation import contemplate
vault_probe = _vault_probe_for_context(self._context) if self._context else None
depth = getattr(self, '_last_node_depths', None)
candidates_to_save = [
contemplate(c, vault_probe=vault_probe, depth=depth)
contemplate(c, vault_probe=vault_probe)
for c in candidates_to_save
]
# ADR-0219 — generation-dir atomic checkpoint. All files are written
@ -979,10 +970,8 @@ class ChatRuntime:
vault_probe = (
_vault_probe_for_context(self._context) if self._context else None
)
# 3-lang depth propagation contract (see checkpoint_engine_state)
depth = getattr(self, '_last_node_depths', None)
contemplated = [
contemplate(candidate, vault_probe=vault_probe, depth=depth)
contemplate(candidate, vault_probe=vault_probe)
for candidate in self._pending_candidates
]
contemplated_count = len(contemplated)
@ -1550,10 +1539,8 @@ class ChatRuntime:
if self.config.vault_probe_discoveries
else None
)
# 3-lang depth propagation contract (see checkpoint_engine_state)
depth = getattr(self, '_last_node_depths', None)
candidates = tuple(
contemplate(c, vault_probe=vault_probe, depth=depth) for c in candidates
contemplate(c, vault_probe=vault_probe) for c in candidates
)
self._pending_candidates.extend(candidates)
sink = self._discovery_sink

View file

@ -1,18 +1,19 @@
"""Project-root conftest — test classification registries.
The QUARANTINE set is the only allowed registry for known-failing tests.
It is currently empty. If it ever contains nodeids, CI excludes them via
``-m "not quarantine"`` (smoke, full-pytest fast lane, nightly full).
The suite is a ratchet: a quarantined test removed from this set must pass
It is currently empty. If it ever contains nodeids, the CI gate at
.github/workflows/full-pytest.yml runs ``pytest -m "not quarantine"``
so those explicitly tracked failures do not block unrelated PRs. The
suite is a ratchet: a quarantined test removed from this set must pass
on its own merits.
See docs/test-debt-quarantine.md for current policy and historical cluster
diagnoses. See docs/testing-lanes.md for CI lane policy (PR / main / nightly).
diagnoses.
To remove a test from quarantine:
1. Land a PR that makes the test pass.
2. Delete its entry from QUARANTINE in the same PR.
3. The main fast gate and nightly full gate will both require it to pass.
3. The full-pytest CI gate will now require it to keep passing.
Adding a test to QUARANTINE is strongly discouraged. If a new
failure surfaces, the right default is to fix it in the PR that
@ -79,14 +80,12 @@ QUARANTINE: frozenset[str] = frozenset()
# a developer run a fast lane locally. Classification adds the ``slow`` marker
# ONLY — it never skips — so ``-m slow`` SELECTS these tests. Choose a lane:
#
# fast lane: pytest -m "not quarantine and not slow" (make test-fast;
# also full-pytest.yml on main)
# fast lane: pytest -m "not quarantine and not slow" (make test-fast)
# slow lane: pytest -m "slow and not quarantine" (make test-slow)
# full lane: pytest -m "not quarantine" (make test-full;
# also nightly-full-pytest.yml)
# full lane: pytest -m "not quarantine" (make test-full; CI)
#
# CI policy: PR = smoke subset; main = fast lane; nightly = full including
# slow. See docs/testing-lanes.md.
# CI is unchanged: smoke.yml and full-pytest.yml run ``-m "not quarantine"``,
# which still includes slow tests. See docs/testing-lanes.md.
# ---------------------------------------------------------------------------
# Whole-file: the cost is carried by a module/session-scoped fixture, so marking

View file

@ -1,16 +0,0 @@
"""CORE ABI namespace.
Exposes GeometricDelta and its validation routines.
"""
from core.abi.geometric_delta import GeometricDelta
from core.abi.geometric_delta_validator import (
GeometricDeltaValidationError,
validate_geometric_delta,
)
__all__ = [
"GeometricDelta",
"GeometricDeltaValidationError",
"validate_geometric_delta",
]

View file

@ -1,29 +0,0 @@
"""GeometricDelta ABI Definition.
Single source of truth for the GeometricDelta struct which defines the boundary
between any modality compiler (like Sopher's Callosum) and the Master substrate (CORE).
"""
from dataclasses import dataclass
from typing import Any, Dict, List, Optional, Set
from core.epistemic_state import EpistemicState
@dataclass(frozen=True)
class GeometricDelta:
"""The canonical ABI for field updates to the Master substrate.
All compilers must emit exactly this type, and it must pass the guarded closure
projector at the boundary.
"""
id: str # content-addressed hash
parents: Set[str] # CRDT frontier IDs
modality: str # e.g. "lh_text", "sensor", "tool"
compiler_id: str # name+version of compiler
semantic: Dict[str, Any] # typed primitive (enum + payload)
amr_scope: Dict[str, Any] # resolution + region metadata
delta_versor: List[float] # 32 components, Cl(4,1) basis
inverse_ref: Optional[str] # optional correction link
provenance: Dict[str, Any] # source, time, adr_refs, hash
epistemic: EpistemicState # CORE truth-seeking state

View file

@ -1,84 +0,0 @@
"""Validation contracts for GeometricDelta.
Ensures that any update to the Master substrate complies with Cl(4,1) shape
invariants, provenance metadata, and truth-seeking constraints.
"""
import os
from typing import Tuple
from core.abi.geometric_delta import GeometricDelta
from core.epistemic_state import EpistemicState
DEFAULT_TOLERANCE = 1e-6
class GeometricDeltaValidationError(ValueError):
"""Raised when a GeometricDelta violates the ABI contract."""
pass
def validate_geometric_delta(delta: GeometricDelta, tolerance: float | None = None) -> Tuple[bool, str]:
"""Validates the structure, metadata, and closure of a GeometricDelta.
Returns:
(True, "") if valid.
(False, reason) if invalid.
Raises:
GeometricDeltaValidationError: If strict checks are failed.
"""
if tolerance is None:
try:
tolerance = float(os.getenv("CORE_ABI_TOLERANCE", str(DEFAULT_TOLERANCE)))
except ValueError:
tolerance = DEFAULT_TOLERANCE
# 1. Shape and basis check
if not isinstance(delta.delta_versor, list):
raise GeometricDeltaValidationError("delta_versor must be a list of floats")
if len(delta.delta_versor) != 32:
raise GeometricDeltaValidationError(
f"delta_versor must have exactly 32 components, got {len(delta.delta_versor)}"
)
if not all(isinstance(x, (int, float)) for x in delta.delta_versor):
raise GeometricDeltaValidationError("delta_versor must contain only numeric values")
# 2. Epistemic state check
if not isinstance(delta.epistemic, EpistemicState):
raise GeometricDeltaValidationError(
f"epistemic must be an instance of EpistemicState, got {type(delta.epistemic)}"
)
# 3. Provenance structure check
if not isinstance(delta.provenance, dict):
raise GeometricDeltaValidationError("provenance must be a dictionary")
required_provenance_keys = {"source", "time", "hash", "adr_refs"}
missing_keys = required_provenance_keys - set(delta.provenance.keys())
if missing_keys:
raise GeometricDeltaValidationError(
f"provenance missing required keys: {missing_keys}"
)
# 4. AMR scope structure check
if not isinstance(delta.amr_scope, dict):
raise GeometricDeltaValidationError("amr_scope must be a dictionary")
# 5. Closure check stub
# Delegates to guarded projector check (scale + monotone Newton).
# For now, this is a placeholder/contract interface.
# In Sopher or CORE-rs, this triggers the algebraic Cl(4,1) projector.
is_closed, residual = check_cl41_closure_invariant(delta.delta_versor, tolerance)
if not is_closed:
return False, f"Cl(4,1) closure invariant violated: residual {residual} > tolerance {tolerance}"
return True, ""
def check_cl41_closure_invariant(versor: list[float], tolerance: float) -> Tuple[bool, float]:
"""Stub for Cl(4,1) algebraic closure verification.
In full implementation, this calls core-rs or mlx_cl41 to verify
||F * reverse(F) - 1||_F < tolerance.
"""
# Simple placeholder: for now, assume valid or check a simple norm condition.
# If the user has set CORE_STRICT_PROJECTOR, we would execute the guarded projector.
# We return True and a dummy residual of 0.0 for this abstract stub.
return True, 0.0

View file

@ -1,23 +0,0 @@
"""ADR-DAG conformal embedding (R&D-Revised §2.4 / issue #21).
Deterministic embedding of ADR markdown into Cl(4,1) bivector space and
master-blade drift checks for proposal coherence.
"""
from core.adr.validator import (
AdrDagValidationError,
embed_adr_markdown,
master_architecture_blade,
proposal_drift,
simple_bivector_project,
validate_proposal_against_master,
)
__all__ = [
"AdrDagValidationError",
"embed_adr_markdown",
"master_architecture_blade",
"proposal_drift",
"simple_bivector_project",
"validate_proposal_against_master",
]

View file

@ -1,168 +0,0 @@
"""
core/adr/validator.py
ADR-DAG conformal embedding Ψ(M) (R&D-Revised §2.4 / #21).
SHA-256(M) 10×3-byte segments c_k [1, 1]
10 basis bivectors (planes 6..15) simple-bivector projection
master blade = successive wedge of load-bearing ADR embeddings
proposal drift = B_p A_master
Cross-check: does **not** reimplement GeometricDelta ABI validation
(``core/abi/geometric_delta_validator.py``). This module embeds ADR text into
geometry; that module validates GeometricDelta envelopes.
"""
from __future__ import annotations
import hashlib
from typing import Sequence
import numpy as np
from algebra.cl41 import N_COMPONENTS, geometric_product, grade_project
_BIVECTOR_PLANES = tuple(range(6, 16)) # 10 planes
_NEAR_ZERO = 1e-12
_SIMPLE_G4_TOL = 1e-9
class AdrDagValidationError(ValueError):
"""Fail-closed refusal from ADR-DAG embedding / drift checks."""
def __init__(self, reason: str, **disclosure) -> None:
self.reason = reason
self.disclosure = dict(disclosure)
super().__init__(f"adr_dag refused [{reason}]: {self.disclosure}")
def _grade_mass(v: np.ndarray) -> int:
for g in range(5, -1, -1):
if float(np.linalg.norm(grade_project(v, g))) > _NEAR_ZERO:
return g
return 0
def multivector_wedge(A: np.ndarray, B: np.ndarray) -> np.ndarray:
"""Grade-raising wedge approximation: grade-project of geometric product.
For pure blades this matches the outer product grade. Used for master-blade
assembly and drift (B_p A_master).
"""
a = np.asarray(A, dtype=np.float64)
b = np.asarray(B, dtype=np.float64)
ga, gb = _grade_mass(a), _grade_mass(b)
target = min(5, ga + gb)
if target == 0:
return grade_project(geometric_product(a, b), 0)
return grade_project(geometric_product(a, b), target).astype(np.float64)
def simple_bivector_project(B: np.ndarray) -> np.ndarray:
"""Project a multivector generator onto a simple bivector.
Spec intent: pure grade-2 support that is *simple* (single plane). Pure
multiplane grade-2 has nontrivial ``B B``; we always collapse to the
dominant plane when more than one plane is occupied (deterministic).
"""
arr = np.asarray(B, dtype=np.float64)
if arr.shape != (N_COMPONENTS,):
raise AdrDagValidationError("bad_shape", shape=tuple(arr.shape))
B2 = grade_project(arr, 2).astype(np.float64)
occupied = [i for i in _BIVECTOR_PLANES if abs(float(B2[i])) > _NEAR_ZERO]
if len(occupied) <= 1:
return B2
# Multiplane → dominant-plane collapse (simple by construction).
best_i = max(occupied, key=lambda i: abs(float(B2[i])))
out = np.zeros(N_COMPONENTS, dtype=np.float64)
out[best_i] = float(B2[best_i])
return out
def embed_adr_markdown(markdown: str) -> np.ndarray:
"""Ψ(M): deterministic SHA-256 → 10 bivector coefficients → simple project.
Identical markdown identical 32-vector (replay pin).
"""
if not isinstance(markdown, str):
raise AdrDagValidationError("not_str", type=type(markdown).__name__)
# Empty markdown is a valid document identity (still deterministic).
digest = hashlib.sha256(markdown.encode("utf-8")).digest() # 32 bytes
B = np.zeros(N_COMPONENTS, dtype=np.float64)
for k, plane in enumerate(_BIVECTOR_PLANES):
# 3-byte segments; last 2 hash bytes unused (spec: 10×3=30).
chunk = digest[k * 3 : k * 3 + 3]
u = int.from_bytes(chunk, "big") # 0 .. 2^24-1
c = (u / float(0xFFFFFF)) * 2.0 - 1.0 # [-1, 1]
B[plane] = c
return simple_bivector_project(B)
def master_architecture_blade(
embeddings: Sequence[np.ndarray],
) -> np.ndarray:
"""Assemble load-bearing ADR embeddings into a master architecture blade.
Prefer successive wedge when non-degenerate; if a wedge step vanishes
(parallel simple planes after projection), fall back to algebraic sum of
simple bivectors so the master never fabricates a zero blade.
"""
if not embeddings:
raise AdrDagValidationError("empty_master_set")
simples = [
simple_bivector_project(np.asarray(e, dtype=np.float64))
for e in embeddings
]
wedge = simples[0].copy()
for i, e in enumerate(simples[1:], start=1):
w = multivector_wedge(wedge, e)
if float(np.linalg.norm(w)) > _NEAR_ZERO:
wedge = w
# else: parallel/collinear under wedge — keep prior wedge, continue
if float(np.linalg.norm(wedge)) > _NEAR_ZERO:
return wedge.astype(np.float64)
# Full wedge chain degenerate: superposition master (still deterministic).
acc = np.zeros(N_COMPONENTS, dtype=np.float64)
for e in simples:
acc = acc + e
if float(np.linalg.norm(acc)) < _NEAR_ZERO:
raise AdrDagValidationError("degenerate_master_blade", at_index=0)
return simple_bivector_project(acc)
def proposal_drift(B_proposal: np.ndarray, A_master: np.ndarray) -> float:
"""Drift = ‖B_p ∧ A_master‖ (Euclidean coeff norm of the wedge)."""
Bp = simple_bivector_project(np.asarray(B_proposal, dtype=np.float64))
Am = np.asarray(A_master, dtype=np.float64)
if Am.shape != (N_COMPONENTS,):
raise AdrDagValidationError("bad_master_shape", shape=tuple(Am.shape))
w = multivector_wedge(Bp, Am)
return float(np.linalg.norm(w))
def validate_proposal_against_master(
proposal_markdown: str,
master_markdowns: Sequence[str],
*,
max_drift: float = 1.0,
) -> tuple[bool, float, np.ndarray, np.ndarray]:
"""Embed proposal + masters; return (ok, drift, B_p, A_master)."""
if not master_markdowns:
raise AdrDagValidationError("empty_master_set")
masters = [embed_adr_markdown(m) for m in master_markdowns]
A = master_architecture_blade(masters)
Bp = embed_adr_markdown(proposal_markdown)
d = proposal_drift(Bp, A)
ok = bool(d <= float(max_drift) + _NEAR_ZERO)
return ok, d, Bp, A
__all__ = [
"AdrDagValidationError",
"embed_adr_markdown",
"master_architecture_blade",
"multivector_wedge",
"proposal_drift",
"simple_bivector_project",
"validate_proposal_against_master",
]

View file

@ -2,7 +2,7 @@
Wires the five follow-up items from ADR-0091 §"Follow-up Work" into a
single evidence-bearing report. The existing parser
(:func:`packs.domain_contract.parse_domain_contract`) handles
(:func:`language_packs.domain_contract.parse_domain_contract`) handles
structural validation; this module layers the nine semantic predicates
from ADR-0091 §"Validation Semantics" on top.
@ -34,7 +34,7 @@ from core.capability.reviewers import (
load_reviewer_registry,
)
from core.capability.sources import LEDGER_SOURCES
from packs.domain_contract import (
from language_packs.domain_contract import (
DomainContractValidation,
DomainPackContract,
validate_domain_contract_pack,
@ -113,7 +113,7 @@ def _predicate_p1_manifest_valid(
lands, this predicate inherits the improvement.
"""
try:
from packs import compiler as pack_compiler
from language_packs import compiler as pack_compiler
loader = getattr(pack_compiler, "load_pack", None)
if loader is None:
@ -121,7 +121,7 @@ def _predicate_p1_manifest_valid(
predicate_id="P1",
title="manifest/checksum valid",
passed=False,
notes="packs.compiler.load_pack not available",
notes="language_packs.compiler.load_pack not available",
)
loader(pack_id)
except Exception as exc: # pylint: disable=broad-except
@ -486,7 +486,7 @@ def evaluate_domain_contract(
- ``reviewer_registry`` injects a parsed registry (avoids re-loading
from disk per pack).
"""
root = data_root or (_REPO_ROOT / "packs" / "data")
root = data_root or (_REPO_ROOT / "language_packs" / "data")
validation: DomainContractValidation = validate_domain_contract_pack(
pack_id, data_root=root

View file

@ -49,7 +49,7 @@ _REPO_ROOT = Path(__file__).resolve().parent.parent.parent
# The math domain's operator pack — same constant the solver uses.
DEFAULT_MATH_PACK_ID: str = "en_arithmetic_v1"
DEFAULT_MATH_LEXICON: Path = (
_REPO_ROOT / "packs" / "data" / DEFAULT_MATH_PACK_ID / "lexicon.jsonl"
_REPO_ROOT / "language_packs" / "data" / DEFAULT_MATH_PACK_ID / "lexicon.jsonl"
)
# Default B3 lane location.

View file

@ -29,7 +29,7 @@ from core.capability.reviewers import (
)
from core.capability.sources import LEDGER_SOURCES
from core.config import DEFAULT_CONFIG
from packs.domain_contract import validate_domain_contract_pack
from language_packs.domain_contract import validate_domain_contract_pack
_REPO_ROOT = Path(__file__).resolve().parent.parent.parent
_CHAINS_PER_OPERATOR_DOMAIN = 8
@ -109,12 +109,12 @@ def _latest_eval_result(lane: str, version: str, split: str) -> dict[str, Any]:
def _manifest_for_pack(pack_id: str) -> dict[str, Any]:
path = _REPO_ROOT / "packs" / "data" / pack_id / "manifest.json"
path = _REPO_ROOT / "language_packs" / "data" / pack_id / "manifest.json"
return _load_json(path)
def _pack_lemmas(pack_id: str) -> set[str]:
root = _REPO_ROOT / "packs" / "data" / pack_id
root = _REPO_ROOT / "language_packs" / "data" / pack_id
path = root / "lexicon.jsonl"
lemmas: set[str] = set()
if not path.exists():
@ -139,7 +139,7 @@ def _count_jsonl(path: Path) -> int:
def _pack_metrics(pack_id: str) -> dict[str, Any]:
root = _REPO_ROOT / "packs" / "data" / pack_id
root = _REPO_ROOT / "language_packs" / "data" / pack_id
manifest = _manifest_for_pack(pack_id)
lexicon_path = root / str(manifest.get("lexicon", "lexicon.jsonl"))
glosses_path = root / "glosses.jsonl"

View file

@ -979,7 +979,7 @@ _DEFAULT_OUTPUT_PATH = _MATH_PROPOSALS_DIR / "proposals.jsonl"
def _validate_output_path(raw: str | None) -> Path:
"""Reject output paths that escape teaching/math_proposals/.
Mirrors :func:`packs.compiler._validate_pack_id` trust-boundary
Mirrors :func:`language_packs.compiler._validate_pack_id` trust-boundary
discipline: path-traversal and absolute paths are rejected before any
filesystem access.
@ -1818,14 +1818,6 @@ def cmd_demo(args: argparse.Namespace) -> int:
print(f" {k}: {v}")
return 0
if target == "proof-carrying-promotion":
from evals.proof_carrying_promotion_demo.run_tour import run_tour
result = run_tour(emit_json=args.json)
if args.json:
print(json.dumps(result, indent=2, sort_keys=True, default=str))
return 0 if result.get("all_passed", False) else 1
if target == "audit-tour":
from evals.audit_tour.run_tour import run_tour
@ -2200,7 +2192,7 @@ def _run_demo_all(emit_json: bool) -> int:
passed["learning_arc"] = bool(arc_report.get("learning_arc_closed", False))
# 9. articulation
_section("9/10 articulation — discourse-planner spine")
_section("9/9 articulation — discourse-planner spine")
from evals.articulation.run_demo import run_demo as run_art
if not emit_json:
@ -2210,15 +2202,6 @@ def _run_demo_all(emit_json: bool) -> int:
consolidated["articulation"] = art_report
passed["articulation"] = bool(art_report.get("all_claims_supported", False))
# 10. proof-carrying-promotion
_section("10/10 proof-carrying-promotion — deductive engine pipeline")
from evals.proof_carrying_promotion_demo.run_tour import run_tour as run_pcp
with _maybe_suppress():
pcp_report = run_pcp(emit_json=emit_json)
consolidated["proof_carrying_promotion"] = pcp_report
passed["proof_carrying_promotion"] = bool(pcp_report.get("all_passed", False))
all_passed = all(passed.values())
consolidated["passed"] = passed
consolidated["all_demos_passed"] = all_passed
@ -3362,7 +3345,7 @@ def build_parser() -> argparse.ArgumentParser:
teaching_compile_pack.add_argument(
"--pack",
default=None,
help="pack root path (default: packs/data/en_core_math_v1)",
help="pack root path (default: language_packs/data/en_core_math_v1)",
)
teaching_compile_pack.add_argument(
"--json",
@ -3649,7 +3632,6 @@ def build_parser() -> argparse.ArgumentParser:
"phase5",
"phase6",
"adr-0024-chain",
"proof-carrying-promotion",
"audit-tour",
"register-tour",
"anchor-lens-tour",
@ -3671,9 +3653,8 @@ def build_parser() -> argparse.ArgumentParser:
"phase5: stratified 5-family mechanism-isolation. "
"phase6: 3-condition head-to-head vs in-system baseline. "
"adr-0024-chain: phase5 + phase6 combined evidence. "
"all: run every demo and print a "
"all: run every demo (eight in total) and print a "
"consolidated PASS/FAIL table; exits non-zero if any demo fails. "
"proof-carrying-promotion: ADR-0218 PR D deterministic demo. "
"audit-tour: ADR-0027..0041 pack-layer architecture in four "
"scenes (identity / safety / ethics / replay). "
"register-tour: ADR-0068..0072 presentation-axis seam — same "

View file

@ -48,7 +48,7 @@ def cmd_capability_domain_contract(args: argparse.Namespace) -> int:
The legacy structural-only output remains available via
``--structural-only`` for callers that depend on the prior shape.
"""
from packs.domain_contract import validate_domain_contract_pack
from language_packs.domain_contract import validate_domain_contract_pack
if getattr(args, "structural_only", False):
report = validate_domain_contract_pack(args.pack_id).as_dict()

View file

@ -20,7 +20,7 @@ IMPORT_CHECKS: tuple[tuple[str, str], ...] = (
("demos", "demos.claude_tool_authority"),
("engine_state", "engine_state"),
("evals", "evals.framework"),
("packs", "packs"),
("language_packs", "language_packs"),
("morphology", "morphology.registry"),
("packs", "packs.safety.loader"),
("scripts", "scripts.run_pulse"),
@ -54,13 +54,13 @@ def cmd_doctor(args: argparse.Namespace, *, repo_root: Path = DEFAULT_REPO_ROOT)
if args.packs:
try:
from packs import list_packs
from language_packs import list_packs
packs = list_packs()
except Exception as exc:
ok = False
print(
f"FAIL packs packs.list_packs: {exc.__class__.__name__}: {exc}"
f"FAIL packs language_packs.list_packs: {exc.__class__.__name__}: {exc}"
)
else:
print("packs:")

View file

@ -11,7 +11,7 @@ from core.cli import _die, _REPO_ROOT, _run
def cmd_pack_list(args: argparse.Namespace) -> int:
"""List compiled language packs."""
from packs import list_packs
from language_packs import list_packs
packs = list_packs()
if not packs:
@ -24,7 +24,7 @@ def cmd_pack_list(args: argparse.Namespace) -> int:
def cmd_pack_verify(args: argparse.Namespace) -> int:
"""Verify one language pack checksum."""
return _run(sys.executable, "-m", "packs", "verify", args.pack_id)
return _run(sys.executable, "-m", "language_packs", "verify", args.pack_id)
def cmd_pack_validate(args: argparse.Namespace) -> int:

View file

@ -876,14 +876,14 @@ def cmd_teaching_compile_pack(args: argparse.Namespace) -> int:
"""
from pathlib import Path
from packs.compile_pack import compile_pack
from language_packs.compile_pack import compile_pack
pack_root = (
Path(args.pack)
if args.pack
else (
Path(__file__).resolve().parent.parent
/ "packs"
/ "language_packs"
/ "data"
/ "en_core_math_v1"
)

View file

@ -26,16 +26,6 @@ TEST_SUITES: dict[str, tuple[str, ...]] = {
"tests/test_runtime_config.py",
"tests/test_cognitive_turn_pipeline.py",
"tests/test_architectural_invariants.py",
# Audio sensorium lane — part of the smoke.yml PR gate (compiler,
# CRDT merge, eval gates, pack manifest, mount, teachers; ~3s).
# Listed explicitly so the local-first pre-push gate (AGENTS.md
# protocol) equals the CI gate rather than silently narrowing it.
"tests/test_audio_compiler.py",
"tests/test_audio_crdt_merge.py",
"tests/test_audio_eval_gates.py",
"tests/test_audio_pack_manifest.py",
"tests/test_audio_sensorium_mount.py",
"tests/test_audio_teachers.py",
# ADR-0043 — identity falsifiability: ratified identity packs must
# produce distinct, directionally-correct articulations, with a
# pack-invariant grounding/refusal floor and zero fabrication. Lives
@ -258,7 +248,7 @@ def cmd_check(
"field",
"generate",
"ingest",
"packs",
"language_packs",
"morphology",
"persona",
"sensorium",

View file

@ -32,7 +32,6 @@ from generate.intent_ratifier import (
ratify_intent,
)
from generate.graph_planner import (
GraphNode,
PropositionGraph,
graph_from_intent,
ground_graph,
@ -41,7 +40,6 @@ from generate.graph_planner import (
from recognition.anti_unifier import DerivedRecognizer, recognize
from recognition.carrier import EpistemicGraph, EpistemicNode
from recognition.connector import epistemic_node_to_graph_node
from recognition.depth_canonical import build_node_depths
from generate.realizer import realize_semantic
from generate.intent import IntentTag
from generate.operators import (
@ -127,9 +125,6 @@ class CognitiveTurnPipeline:
) -> None: # runtime: ChatRuntime (no import cycle)
self.runtime = runtime
self._last_node_id: str | None = None
self._current_node_depths: dict = {}
self._current_agent_node_id: str | None = None
self._last_node_depths: dict | None = None
self.teaching_store = teaching_store if teaching_store is not None else TeachingStore()
if recognizer is not None:
self._recognizer = recognizer
@ -173,23 +168,7 @@ class CognitiveTurnPipeline:
# CognitiveTurnResult.refusal_reason when non-empty.
_recognition_refusal_reason: str = ""
if self._recognizer is not None:
# Same-turn depth for recognition: resolve he/grc roots from tokens
# before PropositionGraph exists (plan residual). Prefer early
# provisional t{i} depths; fall back to current/prior-turn graph
# depths for multi-turn chaining (AC1).
from chat.pack_resolver import resolve_token_depths
_early_depths, _early_agent = resolve_token_depths(raw_tokens)
_prior_depths = (
getattr(self, "_current_node_depths", None)
or getattr(self, "_last_node_depths", None)
or {}
)
_depths = _early_depths if _early_depths else _prior_depths
_agent_nid = _early_agent or getattr(self, "_current_agent_node_id", None)
_rec_outcome = recognize(
self._recognizer, raw_tokens, depths=_depths, agent_node_id=_agent_nid
)
_rec_outcome = recognize(self._recognizer, raw_tokens)
if _rec_outcome.admitted:
_ep_node = EpistemicNode(
node_id=f"{self._recognizer.teaching_set_id}:{self._turn_number}",
@ -295,112 +274,15 @@ class CognitiveTurnPipeline:
# ``register_canonical_surface``, ADR-0071 for
# ``pre_decoration_surface``). The historical ``getattr`` calls
# were ADR-introduction defensiveness now safe to drop.
# Grounding (when opted in) produces the effective graph for the
# supremacy decision + stored result + topological hash. The
# original intent-derived `graph` is the starting plan; effective
# is the substrate view after recall grounding (when active).
# This ensures the graph carried in CognitiveTurnResult and
# folded into trace_hash reflects the actual reasoning used.
effective_graph = graph
recalled_words = response.recalled_words or ()
# Depth enrichment is now DEFAULT (AC2) for 3-lang mastery on spine.
# ALWAYS attempt per-subject resolution + GraphNode lang/root enrichment
# (independent of is_fully_grounded) so node_depths / graph_anti_unify
# and result fields are populated for both OOV/pending and grounded 3-lang cases.
# The grounded authority flag only controls the recalled_words fill + re-realize.
# Collect unique subjects, resolve with depth packs for language/root/gloss.
# This feeds both recalled_words (for ground_graph) and per-node enrichment.
if effective_graph:
subjects = []
seen = set()
for n in effective_graph.nodes:
s = n.subject.strip().lower()
if s and s not in seen:
seen.add(s)
subjects.append(s)
from chat.pack_resolver import (
DEFAULT_RESOLVABLE_PACK_IDS,
resolve_entry,
resolve_gloss,
resolve_lemma,
)
# Master bidirectional entry point: LexicalResolution carries
# 3-language depth (Hebrew roots, Greek precision) usable for
# graph grounding (comprehension), later realization (articulation),
# and contemplation/reasoning on the shared PropositionGraph.
from chat.pack_resolver import DEPTH_PACK_IDS
depth_pack_ids = DEFAULT_RESOLVABLE_PACK_IDS + DEPTH_PACK_IDS
subject_to_res = {}
for s in subjects:
res = resolve_entry(s, pack_ids=depth_pack_ids)
subject_to_res[s] = res
# Collect glosses for pending nodes in order (feeds ground_graph sequentially)
# (only when not fully grounded, to preserve prior behavior for gloss fill)
if not effective_graph.is_fully_grounded():
recalled_glosses = []
for n in effective_graph.nodes:
obj = n.obj
if obj in (None, "", "<pending>", "<prior>") or (isinstance(obj, str) and "..." in obj):
s = n.subject.strip().lower()
res = subject_to_res.get(s)
if res and getattr(res, 'gloss', None):
recalled_glosses.append(res.gloss)
elif resolve_lemma(n.subject):
# legacy fallback per-subject
g = resolve_gloss(n.subject)
if g:
_, _, gloss_text = g
if gloss_text:
recalled_glosses.append(gloss_text)
if recalled_glosses:
recalled_words = tuple(recalled_glosses)
# Enrich every node with its subject's resolution (subject→node map)
# Immutable; only rebuild if any depth present. ALWAYS for 3-lang depth support.
if subject_to_res:
new_nodes = []
changed = False
for n in effective_graph.nodes:
s = n.subject.strip().lower()
res = subject_to_res.get(s)
if res and (getattr(res, 'language', None) or getattr(res, 'root', None) or getattr(res, 'morphology_id', None)):
enriched = GraphNode(
node_id=n.node_id,
subject=n.subject,
predicate=n.predicate,
obj=n.obj,
source_intent=n.source_intent,
language=getattr(res, 'language', None),
root=getattr(res, 'root', None),
morphology_id=getattr(res, 'morphology_id', None),
)
new_nodes.append(enriched)
changed = True
else:
new_nodes.append(n)
if changed:
effective_graph = PropositionGraph(
nodes=tuple(new_nodes),
edges=effective_graph.edges,
)
if self.runtime.config.realizer_grounded_authority and recalled_words:
# Ground using recalled_words + depth map (alongside) so
# 3-lang info propagates even if not pre-enriched on nodes.
# Flag only gates this recall-fill step for compat.
depth_map = {}
for n in effective_graph.nodes:
if n.language or n.root or n.morphology_id:
depth_map[n.node_id] = (n.language, n.root, n.morphology_id)
grounded_graph = ground_graph(effective_graph, recalled_words, depth=depth_map)
realized_plan = realize_semantic(target, grounded_graph)
effective_graph = grounded_graph
if self.runtime.config.realizer_grounded_authority:
recalled_words = response.recalled_words
if recalled_words:
grounded_graph = ground_graph(graph, recalled_words)
realized_plan = realize_semantic(target, grounded_graph)
gate_fired = (
response.vault_hits == 0
and response.grounding_source not in ("vault", "pack", "teaching")
and response.grounding_source != "vault"
)
canonical = response.register_canonical_surface
pre_decoration = response.pre_decoration_surface
@ -427,13 +309,6 @@ class CognitiveTurnPipeline:
entailment_trace = self._maybe_entailment_trace(intent, triples)
# === SHADOW COHERENCE GATE WIRING ===
# Graph + realizer already executed unconditionally above.
# Pass the effective (possibly grounded) graph so the gate can
# apply the strict supremacy test. Assessment=None for Phase A
# (assessments still live primarily in derivation organs). When
# the main spine carries ProblemFrame through the turn, this
# becomes the active contract backpressure site.
resolved = resolve_surface(
canonical_surface=canonical,
pre_decoration_surface=pre_decoration,
@ -444,89 +319,10 @@ class CognitiveTurnPipeline:
gate_fired=gate_fired,
walk_surface=walk_surface,
compose_surface=compose_surface,
proposition_graph=effective_graph,
contract_assessment=None,
)
surface = resolved.surface
articulation_surface = resolved.articulation_surface
# SUBSTRATE_BYPASS_HAZARD telemetry (data-driven roadmap).
# Only populated when a graph existed yet substrate did not win.
# This is *observability only* — never used to change control flow
# after the fact, never folded into trace_hash in Phase A.
substrate_hazard: tuple[str, ...] = ()
if effective_graph is not None and resolved.authority not in ("substrate_realizer", "realizer"):
reasons: list[str] = []
if not effective_graph.is_fully_grounded():
reasons.append("unfilled_pending_slots")
# include the exact nodes for precision (Strangler diagnostic)
unresolved = effective_graph.get_unresolved_topology()
if unresolved:
reasons.append(f"unresolved_nodes={unresolved}")
if gate_fired:
reasons.append("unknown_domain_gate_fired")
if not _is_useful_surface(realized_plan.surface):
reasons.append("realizer_surface_not_useful")
substrate_hazard = tuple(reasons)
# Phase C (Geometric Anti-Unification) — read-only telemetry instrumentation.
# Captures the graph-structural context around any OOV/pending "hole"
# so that a future exact-CGA sub-graph anti-unifier can operate on
# conformal neighbors rather than lexical token match.
# Populated observationally; never affects surface, hash (yet), or
# any durable mutation. Uses only what the substrate already produced.
oov_geometric_context = None
grounding_src = getattr(response, "grounding_source", "") or ""
has_pending = bool(effective_graph and any(
(n.obj or "") in ("", "<pending>") or "..." in (n.obj or "")
for n in effective_graph.nodes
))
# AC2: node_depths in oov_geometric_context by default for all PropGraph paths
# Use pure build_node_depths for canonical extraction (nid-keyed).
node_depths = build_node_depths(effective_graph.nodes) if effective_graph else {}
if grounding_src == "oov" or has_pending:
oov_geometric_context = {
"unresolved_topology": effective_graph.get_unresolved_topology() if effective_graph else (),
"intent_tag": getattr(intent, "tag", None).value if intent and getattr(intent, "tag", None) else "unknown",
"geometric_probe_performed": False,
"note": "Hook for geometric anti-unification: surrounding realized facts (via exact vault cga_inner) can infer relation type / SPECULATIVE var for the hole instead of lexical fallback.",
"node_depths": node_depths,
}
else:
# default for PropGraph: at least node_depths
if effective_graph:
oov_geometric_context = {
"node_depths": node_depths,
"note": "default depth context for PropGraph (AC2)",
}
# Phase 4: include graph-level anti-unify result (unresolved topo + roots) for observability on spine.
if node_depths and effective_graph:
try:
from recognition.anti_unifier import graph_anti_unify
topo = tuple(n.node_id for n in effective_graph.nodes)
if oov_geometric_context is None:
oov_geometric_context = {}
oov_geometric_context["graph_anti_unify"] = graph_anti_unify(topo, node_depths)
except Exception:
# Best-effort telemetry only; anti-unify failure must not affect main path.
pass
# Capture depths (post-enrich) to attrs for recognize chaining (AC1) + runtime contemplate depth= (real).
# Propagation contract (3-lang depth on PropGraph spine): pipeline (after OOV/PropGraph construction)
# writes _last_node_depths (and now also top-level on CognitiveTurnResult) so that
# runtime.contemplate(...) and teaching/contemplation paths forward depth= without
# re-resolving packs. Depths originate from pack_resolver + build_node_depths on GraphNode.
# This is the current minimal cross-component channel (observational). See docs/ and review.
if node_depths:
self._current_node_depths = node_depths
if effective_graph and effective_graph.nodes:
self._current_agent_node_id = effective_graph.nodes[0].node_id
self._last_node_depths = node_depths
# Direct assignment now that runtime explicitly declares the attr (cleanup of hasattr/setattr dance)
self.runtime._last_node_depths = node_depths
# Track last node id for correction-intent chaining
if graph.nodes:
self._last_node_id = graph.nodes[-1].node_id
@ -634,22 +430,6 @@ class CognitiveTurnPipeline:
# recognition wins (earlier-fail boundary) over generation.
_generation_refusal_reason = getattr(response, "refusal_reason", "") or ""
refusal_reason = _recognition_refusal_reason or _generation_refusal_reason
# Phase B — Quantized Topological Hashing for the cognitive spine.
# Include the discrete (string-only) topological form of the
# PropositionGraph that was produced for this turn. This is the
# Merkle-DAG of the "think" step (nodes + directed relations).
# - Uses graph.to_json() which is canonical, sort_keys JSON of
# the DAG (no floats, no geometry).
# - Conditional on presence (already is) but the key is only added
# in compute_trace_hash when non-empty, preserving byte identity
# for any legacy pre-inclusion behavior in other contexts.
# - Addresses the Trace Equivalence Hazard: same topology on any
# hardware/backend produces identical contribution to the SHA.
# The continuous versor_condition (rounded) is kept only as the
# runtime guard; actual geometric state lives in field/vault and
# is never raw-hashed here.
graph_topo = effective_graph.to_json() if effective_graph is not None else ""
trace_hash = compute_trace_hash(
input_text=text,
filtered_tokens=filtered_tokens,
@ -668,7 +448,6 @@ class CognitiveTurnPipeline:
ratification_outcome=_trace_ratification_outcome,
region_was_unconstrained=region_was_unconstrained,
refusal_reason=refusal_reason,
proposition_graph=graph_topo,
)
# ADR-0153 (W-020a) — back-stamp the canonical trace_hash onto
@ -708,14 +487,7 @@ class CognitiveTurnPipeline:
vault_hits=response.vault_hits,
recall_energy_class=response.recall_energy_class,
intent=intent,
# Use effective_graph (the post-grounding view when substrate
# grounding was active) so that the stored PropositionGraph
# reflects what the Shadow Coherence Gate / realizer actually
# used for articulation. This makes result.proposition_graph
# + trace hash (via topo) consistent with the executed spine.
# For the common case (no grounding) this is identical to the
# intent-derived graph.
proposition_graph=effective_graph,
proposition_graph=graph,
articulation_target=target,
teaching_candidate=teaching_candidate,
reviewed_teaching_example=reviewed_example,
@ -732,17 +504,6 @@ class CognitiveTurnPipeline:
versor_condition=response.versor_condition,
trace_hash=trace_hash,
leeway=leeway,
# Phase A — Shadow Coherence Gate observability.
# authority_source makes the winner of the substrate vs legacy
# decision first-class evidence (visible in trace, workbench,
# evals). substrate_hazard is the precise bypass signal.
authority_source=resolved.authority,
substrate_hazard=substrate_hazard,
oov_geometric_context=oov_geometric_context,
# 3-lang depth unification: surface the same data at top level on result
# (extracted from pre-computed node_depths var or oov_geometric_context to keep single source)
node_depths=node_depths if node_depths else None,
graph_anti_unify=(oov_geometric_context or {}).get("graph_anti_unify") if oov_geometric_context else None,
)
# ------------------------------------------------------------------

View file

@ -27,19 +27,7 @@ from chat.dispatch_trace import DispatchTrace
@dataclass(frozen=True, slots=True)
class CognitiveTurnResult:
"""Full observability record for a single pipeline turn.
Includes the Shadow Coherence Gate evidence (authority_source +
substrate_hazard) so that the migration from hybrid legacy spine to
the unified PropositionGraph substrate is completely inspectable and
replay-diagnosable without ever breaking determinism or the 74 invariants.
3-lang depth fields (node_depths, graph_anti_unify) are populated for
he/grc PropGraph turns from the same data used for oov_geometric_context.
They are read-only / observational and never affect trace_hash or behavior.
The depth propagation contract (pipeline -> runtime _last_node_depths ->
contemplate(..., depth=) -> teaching) is documented alongside the code.
"""
"""Full observability record for a single pipeline turn."""
# --- input layer ---
input_text: str
@ -154,52 +142,3 @@ class CognitiveTurnResult:
# --- response-governance leeway evidence (B4; observational, not in trace_hash) ---
leeway: LeewayRecord | None = None
# --- Shadow Coherence Gate / substrate authority (Phase A) ---
# ``authority_source`` is the value from SurfaceResolution.authority:
# "runtime_canonical" | "runtime_pre_decoration" | "runtime" | "realizer" | "substrate_realizer".
# It is the single source of truth for which spine actually spoke.
#
# ``substrate_hazard`` is the machine-readable list of reasons the
# geometric substrate was *not* granted authority on this turn even
# though a PropositionGraph was produced. Populated only on bypass
# paths. Observational (not folded into trace_hash in Phase A) so that
# every existing turn keeps byte-identical hashes while the hazard
# ledger illuminates the exact work remaining for Layers 1-3.
#
# These two fields turn the "Authority Flip Cliff" into a controlled,
# data-driven strangler migration.
authority_source: str = ""
substrate_hazard: tuple[str, ...] = ()
# --- Phase C instrumentation: Geometric Anti-Unification hook for OOV (read-only telemetry) ---
# When an OOV subject is encountered in the context of a PropositionGraph
# (i.e. a "hole" in S-P-[OOV] or similar), this carries the discrete
# structural context (unresolved topology + intent) plus a placeholder
# for exact CGA neighbor probe results (via vault.recall + cga_inner on
# surrounding realized facts).
#
# Today: purely structural (from effective_graph.get_unresolved_topology()
# when grounding_source indicates oov or pending slots on OOV-shaped
# intents). No vault call yet (keeps change atomic + zero side effects).
#
# Future: perform *exact* geometric anti-unification here (sub-graph
# match on conformal space) to propose SPECULATIVE algebraic variable
# or relation type for the hole, without ever affecting user surface,
# trace_hash (observational), or durable state. Must emit SPECULATIVE,
# respect teaching boundary for any promotion.
#
# Pillars: Mechanical Sympathy (cheap structural + optional exact recall),
# Semantic Rigor (exact CGA only, no approx), Third Door (graph structure
# as first-class for inference instead of lexical substring).
#
# Never folded into trace_hash in this phase. Never mutates field/vault.
oov_geometric_context: dict | None = None
# --- 3-lang depth PropGraph unification observability (read-only, not in trace_hash) ---
# Extracted from the same source as oov_geometric_context["node_depths"] / ["graph_anti_unify"]
# (or the pre-context data) during pipeline construction for he/grc root-aware paths.
# First-class optional fields so callers do not need to reach into the context dict.
# Never folded into trace_hash (observational only, like oov_geometric_context).
node_depths: dict | None = None
graph_anti_unify: dict | None = None

View file

@ -14,12 +14,6 @@ from __future__ import annotations
from dataclasses import dataclass
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from generate.graph_planner import PropositionGraph
from generate.problem_frame_contracts import ContractAssessment
@dataclass(frozen=True, slots=True)
class SurfaceResolution:
@ -28,11 +22,6 @@ class SurfaceResolution:
``authority`` records the prefix authority before deterministic folds
are appended. ``fold_sources`` records which inference suffixes were
appended, in deterministic order.
When authority == "substrate_realizer", the PropositionGraph +
realize_semantic path was granted supremacy by the Shadow Coherence
Gate (strict structural + contract + coherence proof). Legacy runtime
and walk/compose folds are still applied after, never before.
"""
surface: str
@ -68,50 +57,16 @@ def resolve_surface(
gate_fired: bool = False,
walk_surface: str = "",
compose_surface: str = "",
proposition_graph: "PropositionGraph | None" = None,
contract_assessment: "ContractAssessment | None" = None,
) -> SurfaceResolution:
"""Resolve the final turn surface under one explicit policy.
The Shadow Coherence Gate (Strangler Fig Pattern per the refined plan):
- The PropositionGraph and realize_semantic are executed *unconditionally*
on every turn (already true in pipeline before this call).
- Authority is granted to the substrate realizer **only** when the
strict geometric guard passes:
* graph.is_fully_grounded() (no <pending> slots remain)
* contract assessment (if present) is closed (no missing_bindings,
no unresolved_hazards)
* gate did not fire (unknown domain safety)
Versor coherence (< 1e-6) is presupposed by construction at the
boundaries that produced the graph/bindings; it is not re-"repaired"
here.
- When the guard refuses, we fall back to the legacy runtime surface
and the *precise* topological delta is recorded upstream as
SUBSTRATE_BYPASS_HAZARD telemetry. This makes every test run and
every production turn a diagnostic that lights exactly which
ProblemFrame / recall / realizer gaps still block substrate supremacy.
- Legacy "realizer_useful" path is retained only as a transitional
compat shim; the supreme check is the load-bearing decision.
Walk/compose folds are *always* suffixes they never affect the
authority prefix decision.
Three Engineering Pillars are non-negotiable here:
I. Mechanical Sympathy the entire decision is a handful of O(N)
structural inspections on tiny tuples; zero extra alloc, zero
cross-language roundtrip, zero sensitivity to FMA/assoc drift.
II. Semantic Rigor every term ("fully_grounded", "substrate_realizer",
"bypass_hazard") has one precise meaning. No numeric tolerance,
no "good enough" surface.
III. Third Door we did not pick "keep the regex sidecar" nor
"rip it out and break the suite". We built the substrate spine
as the sole authority path and made the old path the observable
bypass that starves itself to zero.
See also: engineer's assessment §1 (Authority Flip Cliff), AGENTS.md
(versor only at owned boundaries, exact recall, kernel substrate rule),
runtime_contracts.md (surface selection contract).
Policy:
1. Runtime/canonical/pre-decoration selects the base authority.
2. A useful realizer surface may replace the prefix only when the
unknown-domain gate did not fire.
3. Walk and compose suffixes are deterministic inference folds. They
append after prefix authority is selected and are never allowed to
re-run or reinterpret the prefix decision.
"""
surface, articulation_surface, authority = _base_runtime_surface(
@ -121,20 +76,10 @@ def resolve_surface(
response_articulation_surface=response_articulation_surface or "",
)
# === SHADOW COHERENCE GATE ===
# Unconditional substrate execution has already occurred.
# We now decide authority strictly.
if not gate_fired and realized_surface:
if _substrate_supreme(proposition_graph, contract_assessment):
surface = realized_surface
articulation_surface = realized_surface
authority = "substrate_realizer"
elif realizer_useful:
# Transitional shim (pre full coverage of grounding + organs).
# Will be removed when hazard frequency for the legacy path hits zero.
surface = realized_surface
articulation_surface = realized_surface
authority = "realizer"
if realizer_useful and not gate_fired:
surface = realized_surface
articulation_surface = realized_surface
authority = "realizer"
fold_sources: list[str] = []
if walk_surface:
@ -161,41 +106,3 @@ def resolve_surface(
authority=authority,
fold_sources=tuple(fold_sources),
)
def _substrate_supreme(
proposition_graph: "PropositionGraph | None",
contract_assessment: "ContractAssessment | None",
) -> bool:
"""Return True only when the geometric substrate has earned authority.
This is the single source of truth for "use the PropositionGraph path
as the cognitive spine instead of legacy runtime/pack/walk".
Conditions (all must hold):
- A graph was produced.
- graph.is_fully_grounded() every slot bound by exact recall or
direct construction (no <pending>).
- If a ContractAssessment is supplied, it must be closed
(zero missing_bindings and zero unresolved_hazards).
(Assessments are still diagnostic-only in many organs; when the
main spine wires ProblemFrame + assess_contracts, this becomes
active backpressure see Layer 3/Phase D.)
Versor coherence is *not* re-checked with a repair here. It is
required by construction at the sites that emit versors (see
VersorBinding and algebra/versor.py). Passing a non-coherent state
here is a programmer error, not a runtime tolerance.
When this returns False the caller (pipeline) must emit the
SUBSTRATE_BYPASS_HAZARD with graph.get_unresolved_topology() so the
failure is actionable rather than silent.
"""
if proposition_graph is None:
return False
if not proposition_graph.is_fully_grounded():
return False
if contract_assessment is not None:
if contract_assessment.missing_bindings or contract_assessment.unresolved_hazards:
return False
return True

View file

@ -8,24 +8,6 @@ The hash captures every meaningful output of a pipeline run so that:
Only stable, semantically meaningful fields are included. Floating-point
values are rounded to 9 decimal places before hashing so that numeric
noise from different hardware does not break determinism within a run.
Phase B (Trace Equivalence Hazard fix per refined plan / engineer's assessment §2):
The PropositionGraph (the "think" structure) is now folded into the hash
via its canonical discrete topological serialization (to_json / as_dict).
This is a pure structural Merkle-DAG of nodes + directed edges with discrete
labels (subjects, predicates, objects, intents, relations). No raw f64
geometry, no versor arrays, no platform-dependent float associativity or FMA.
Continuous versor_condition remains a runtime guard (rounded only for the
hash payload) and is still asserted < 1e-6 exclusively at construction
boundaries (algebra/versor.py, VersorBinding, etc.). The graph inclusion
makes replay equivalence sensitive to the actual substrate reasoning path
while remaining 100% cross-platform (Python, Rust FFI, MLX on Apple Silicon,
x86) and byte-stable for equivalent turns.
New field is included *only* when non-empty, preserving byte-identical
payloads (and thus trace_hashes) for any pre-inclusion turns or turns
without a graph.
"""
from __future__ import annotations
@ -60,7 +42,6 @@ def compute_trace_hash(
ratification_outcome: str = "",
region_was_unconstrained: bool = True,
refusal_reason: str = "",
proposition_graph: str = "",
) -> str:
"""Return a deterministic SHA-256 hex digest over the turn's key outputs.
@ -78,19 +59,6 @@ def compute_trace_hash(
no proposal was emitted. Folded per ADR-0021 §Consequences so replay
detects when a downstream surface was produced under a different
epistemic frame than at the time of recall.
``proposition_graph`` (Phase B) is the *discrete topological*
canonical serialization of the PropositionGraph (typically
graph.to_json() or equivalent as_dict JSON). This captures the
network structure (nodes + directed edges) and discrete labels
that drove the substrate articulation. It is the Merkle-DAG
representation of the "think" step.
It contains only strings, enums, and structural tuples zero raw
floating-point CGA state. This guarantees identical hashes on
Apple Silicon (MLX), x86, Rust FFI paths, etc. The continuous
versor_condition (rounded) remains only as an ephemeral runtime
guard in the payload.
"""
payload = {
"input_text": input_text,
@ -125,15 +93,6 @@ def compute_trace_hash(
# load-bearing in replay equality.
if refusal_reason:
payload["refusal_reason"] = refusal_reason
# Phase B — discrete PropositionGraph topology (Shadow Coherence Gate
# unification). Included only when present so pre-Phase-B turns and
# turns without a graph keep byte-identical payloads/hashes.
# The value is the full canonical JSON of nodes+edges (structural DAG).
# This makes the cognitive spine's reasoning load-bearing for replay
# while obeying Mechanical Sympathy (no FP) and Semantic Rigor (exact
# discrete structure, no approximation).
if proposition_graph:
payload["proposition_graph"] = proposition_graph
serialized = json.dumps(payload, sort_keys=True, ensure_ascii=False)
return hashlib.sha256(serialized.encode("utf-8")).hexdigest()
@ -156,13 +115,7 @@ def hash_admissibility_trace(trace: tuple) -> str:
def trace_hash_from_result(result: "CognitiveTurnResult") -> str:
"""Convenience wrapper — compute the hash directly from a result object.
Phase B: extracts the discrete topological form of proposition_graph
(if present) using its to_json() canonical serialization. This ensures
that any caller using the helper gets the same payload as the direct
compute_trace_hash path in the pipeline.
"""
"""Convenience wrapper — compute the hash directly from a result object."""
intent_tag = result.intent.tag.value if result.intent is not None else "unknown"
review_hash = (
result.reviewed_teaching_example.review_hash
@ -179,20 +132,6 @@ def trace_hash_from_result(result: "CognitiveTurnResult") -> str:
if result.pack_mutation_proposal is not None
else ""
)
# Discrete graph topo for Phase B (quantized topological hashing).
# Uses the stable to_json() of the stored PropositionGraph (nodes +
# edges in their deterministic order, string labels only). Safe across
# all backends; no raw geometry.
graph_topo = ""
pg = getattr(result, "proposition_graph", None)
if pg is not None:
if hasattr(pg, "to_json"):
graph_topo = pg.to_json()
elif hasattr(pg, "as_dict"):
import json as _json
graph_topo = _json.dumps(
pg.as_dict(), sort_keys=True, ensure_ascii=False
)
return compute_trace_hash(
input_text=result.input_text,
filtered_tokens=result.filtered_tokens,
@ -211,5 +150,4 @@ def trace_hash_from_result(result: "CognitiveTurnResult") -> str:
ratification_outcome=getattr(result, "ratification_outcome", ""),
region_was_unconstrained=getattr(result, "region_was_unconstrained", True),
refusal_reason=getattr(result, "refusal_reason", ""),
proposition_graph=graph_topo,
)

View file

@ -2,9 +2,6 @@
ADR-0080: contemplation can emit speculative findings about current
substrate/report evidence, but it cannot ratify, promote, or mutate packs.
ADR-0241 P9: Trace A wave seam may SPECULATIVE-seal standing-wave modes and
emit RESONANT_MODE_CANDIDATE findings never COHERENT, never serve-wired.
"""
from .runner import contemplate_frontier_reports, run_contemplation
@ -15,13 +12,6 @@ from .schema import (
FindingKind,
)
from .snapshot import ContemplationSubstrate
from .wave_seam import (
WaveModeHypothesis,
WaveReconstructResult,
reconstruct_as_evidence,
reconstruct_as_hypothesis,
speculative_seal_from_contemplation,
)
__all__ = [
"ContemplationEvidenceRef",
@ -29,11 +19,6 @@ __all__ = [
"ContemplationRun",
"ContemplationSubstrate",
"FindingKind",
"WaveModeHypothesis",
"WaveReconstructResult",
"contemplate_frontier_reports",
"reconstruct_as_evidence",
"reconstruct_as_hypothesis",
"run_contemplation",
"speculative_seal_from_contemplation",
]

View file

@ -127,7 +127,7 @@ runs and ADR-0055 discovery candidates.
| SPECULATIVE-only invariant | `ContemplationFinding.__post_init__` raises on any non-SPECULATIVE status | always | ✅ pinned by test |
| Deterministic replay | two `contemplate_*` calls on the same inputs → identical `run_id` and `as_dict()` | byte-identical | ✅ pinned by test |
| Sink path is additive | the `ContemplationRun` blob is byte-identical whether or not a sink is supplied | byte-identical | ✅ pinned by test |
| No pack mutation | `packs/` tree mtimes unchanged across a `contemplate_*` invocation | true | ✅ pinned by test |
| No pack mutation | `language_packs/` tree mtimes unchanged across a `contemplate_*` invocation | true | ✅ pinned by test |
| Predicate split | `missed_contradiction` and `false_contradiction_flag` produce distinct `proposed_action` text | distinct | ✅ pinned by test |
| Lane config_hash separation | `contemplate_frontier_reports` and `contemplate_contradiction_reports` produce distinct `config_hash` on identical input paths | distinct | ✅ pinned by test |

View file

@ -25,8 +25,6 @@ class FindingKind(Enum):
OOV_GAP = "oov_gap"
PLANNER_GAP = "planner_gap"
PACK_MUTATION_CANDIDATE = "pack_mutation_candidate"
# ADR-0241 P9 Trace A: speculative standing-wave mode sealed for review.
RESONANT_MODE_CANDIDATE = "resonant_mode_candidate"
def _canonical_json(payload: dict[str, Any]) -> str:

View file

@ -1,193 +0,0 @@
"""P9 Trace A seam — contemplation → SPECULATIVE holographic standing-wave seal.
ADR-0241 cohesion package P9:
1. Contemplation may **SPECULATIVE-seal** standing-wave modes via
:meth:`HolographicVaultStore.seal_mode` only.
2. Never writes COHERENT teaching corridor / authorized
``seal_mode_reviewed`` remains outside this module.
3. Resonant reconstruct is available as a **hypothesis** over the full
spectrum, or as **evidence** only when ``min_status=COHERENT``.
4. Serve path stays quarantined (no import from ``chat/runtime.py``).
5. No direct ``VaultStore.store`` INV-21 writes stay in holographic_vault.
This module is the living-system bridge for Trace A without collapsing
the teaching / serve containment boundary.
"""
from __future__ import annotations
from dataclasses import dataclass
from typing import Any, Literal
import numpy as np
from core.contemplation.schema import (
ContemplationEvidenceRef,
ContemplationFinding,
FindingKind,
)
from core.physics.holographic_vault import (
HolographicVaultError,
HolographicVaultStore,
SealedMode,
)
from teaching.epistemic import EpistemicStatus
@dataclass(frozen=True, slots=True)
class WaveModeHypothesis:
"""SPECULATIVE seal + contemplation finding for teaching review."""
sealed: SealedMode
finding: ContemplationFinding
standing: Literal["hypothesis"] = "hypothesis"
def as_dict(self) -> dict[str, Any]:
return {
"standing": self.standing,
"mode_id": self.sealed.mode_id,
"vault_index": self.sealed.vault_index,
"epistemic_status": self.sealed.epistemic_status.value,
"finding": self.finding.as_dict(),
}
@dataclass(frozen=True, slots=True)
class WaveReconstructResult:
"""Reconstructed field with honest epistemic standing label."""
psi_hat: np.ndarray
coeffs: np.ndarray
energies: np.ndarray
spectrum: tuple[SealedMode, ...]
standing: Literal["hypothesis", "evidence"]
min_status: EpistemicStatus | None
def as_dict(self) -> dict[str, Any]:
return {
"standing": self.standing,
"min_status": None if self.min_status is None else self.min_status.value,
"mode_ids": [s.mode_id for s in self.spectrum],
"coeff_count": int(self.coeffs.shape[0]),
}
def speculative_seal_from_contemplation(
store: HolographicVaultStore,
psi: np.ndarray,
*,
substrate_hash: str,
subject: str,
mode_id: str | None = None,
notes: str = "",
predicate: str = "propose_standing_wave_mode",
) -> WaveModeHypothesis:
"""SPECULATIVE-seal a closed mode and emit a contemplation finding.
Fail-closed on non-closed / high-drift ψ (delegates to holographic admit).
Does **not** accept an authorization flag COHERENT promotion is not
available on this seam.
"""
if not str(substrate_hash).strip():
raise ValueError("substrate_hash is required for Trace A provenance")
if not str(subject).strip():
raise ValueError("subject is required")
meta: dict[str, Any] = {
"source": "contemplation_trace_a",
"substrate_hash": substrate_hash,
"notes": notes,
"adr_refs": ["ADR-0241", "ADR-0080"],
}
sealed = store.seal_mode(psi, mode_id=mode_id, metadata=meta)
if sealed.epistemic_status is not EpistemicStatus.SPECULATIVE:
# Defensive: seal_mode contract is SPECULATIVE-only; never promote here.
raise RuntimeError(
"Trace A seam integrity breach: seal_mode returned non-SPECULATIVE"
)
mid = sealed.mode_id
finding = ContemplationFinding(
kind=FindingKind.RESONANT_MODE_CANDIDATE,
subject=subject,
predicate=predicate,
object=mid,
evidence_refs=(
ContemplationEvidenceRef(
source_type="holographic_vault",
source_id=mid,
pointer=f"vault_index:{sealed.vault_index}",
summary=(
"SPECULATIVE standing-wave mode sealed for teaching review; "
"not admissible as COHERENT evidence"
),
),
),
proposed_action="review_standing_wave_mode",
substrate_hash=substrate_hash,
epistemic_status=EpistemicStatus.SPECULATIVE,
)
return WaveModeHypothesis(sealed=sealed, finding=finding, standing="hypothesis")
def reconstruct_as_hypothesis(
store: HolographicVaultStore,
psi_query: np.ndarray,
) -> WaveReconstructResult:
"""Superposition reconstruct over the full spectrum (incl. SPECULATIVE).
Result standing is always ``hypothesis`` never claim reviewed evidence.
"""
psi_hat, coeffs, energies, spectrum = store.resonant_reconstruct(psi_query)
return WaveReconstructResult(
psi_hat=psi_hat,
coeffs=coeffs,
energies=energies,
spectrum=spectrum,
standing="hypothesis",
min_status=None,
)
def reconstruct_as_evidence(
store: HolographicVaultStore,
psi_query: np.ndarray,
) -> WaveReconstructResult:
"""Superposition reconstruct over COHERENT modes only.
SPECULATIVE modes are excluded. Empty COHERENT spectrum refuses so
unreviewed hypothesis mass cannot masquerade as evidence.
"""
try:
psi_hat, coeffs, energies, spectrum = store.resonant_reconstruct(
psi_query,
min_status=EpistemicStatus.COHERENT,
)
except HolographicVaultError as exc:
if exc.reason == "empty_spectrum":
raise HolographicVaultError(
"empty_spectrum",
detail=(
"evidence reconstruct requires COHERENT standing-wave modes; "
"SPECULATIVE hypothesis mass is excluded"
),
) from exc
raise
return WaveReconstructResult(
psi_hat=psi_hat,
coeffs=coeffs,
energies=energies,
spectrum=spectrum,
standing="evidence",
min_status=EpistemicStatus.COHERENT,
)
__all__ = [
"WaveModeHypothesis",
"WaveReconstructResult",
"reconstruct_as_evidence",
"reconstruct_as_hypothesis",
"speculative_seal_from_contemplation",
]

View file

@ -160,62 +160,10 @@ def canonical_json(payload: dict[str, Any]) -> bytes:
_TRACKED_MODULES: tuple[str, ...] = (
"chat.telemetry",
"chat.runtime",
"packs.compiler",
"language_packs.compiler",
)
# Env keys whose values are host/isolation paths. Mutation is still
# detected (key present/absent/changed), but absolute path *values*
# never enter divergence messages — those would make lane SHA pins
# depend on tempfile locations and break hermetic CI.
_PATH_LIKE_ENV_SUFFIXES: tuple[str, ...] = ("_DIR", "_PATH", "_HOME", "_ROOT")
def _is_path_like_env_key(key: str) -> bool:
if key == "CORE_ENGINE_STATE_DIR":
return True
return any(key.endswith(suffix) for suffix in _PATH_LIKE_ENV_SUFFIXES)
def _format_env_value(key: str, value: str) -> str:
"""Stable, pin-safe rendering of an env value for divergence text."""
if _is_path_like_env_key(key):
return "<path>"
return value
def _env_subset_divergences(
before_env: tuple[tuple[str, str], ...] | tuple[()] | Any,
after_env: tuple[tuple[str, str], ...] | tuple[()] | Any,
) -> tuple[str, ...]:
"""Key-level env delta — not a full before/after dump.
Full tuple dumps embed every ambient ``CORE_*`` value (including
hermetic engine-state temp paths). That is correct for *detection*
when compared as raw snapshots, but wrong for *report text*: the
lane SHA pin must be host-independent. Only keys that actually
changed appear in the message.
"""
before_map = dict(before_env or ())
after_map = dict(after_env or ())
messages: list[str] = []
for key in sorted(set(before_map) | set(after_map)):
b = before_map.get(key)
a = after_map.get(key)
if b == a:
continue
if b is None:
messages.append(f"env_subset: +{key}={_format_env_value(key, a)}")
elif a is None:
messages.append(f"env_subset: -{key}={_format_env_value(key, b)}")
else:
messages.append(
"env_subset: "
f"{key} {_format_env_value(key, b)!r} -> {_format_env_value(key, a)!r}"
)
return tuple(messages)
def _global_state_snapshot() -> dict[str, Any]:
"""Capture a load-bearing subset of process state for diff checking.
@ -258,14 +206,9 @@ def verify_no_global_state_mutation(
when the adapter does its own deferred imports. Only id id
rebindings (the module object was replaced) and value-set
divergences on env vars are flagged.
Env divergences are reported as a **key-level delta** (added /
removed / changed keys). Full before/after env dumps are forbidden
in the divergence text: they embed host-volatile values such as
``CORE_ENGINE_STATE_DIR`` temp paths and make lane SHA pins flaky.
"""
divergences: list[str] = []
for key in sorted(set(before.keys()) | set(after.keys())):
for key in set(before.keys()) | set(after.keys()):
b = before.get(key)
a = after.get(key)
if b == a:
@ -274,10 +217,9 @@ def verify_no_global_state_mutation(
# Lazy import: a module that wasn't yet loaded is now
# loaded. Benign and unavoidable.
continue
if key == "env_subset":
divergences.extend(_env_subset_divergences(b, a))
continue
divergences.append(f"{key}: before={b!r} after={a!r}")
divergences.append(
f"{key}: before={b!r} after={a!r}"
)
return (not divergences, tuple(divergences))

View file

@ -41,11 +41,7 @@ from core.demos.tour_adapters import RegisterTourDemo
SHOWCASE_VERSION: int = 1
# Post-CGA substrate + denser spine work: cold RegisterTour alone is ~30s+
# on typical dev hardware. 60s is the honest reference budget that still
# catches pathological regressions without false-failing content lanes.
# See evals/public_demo/contract.md "Known Environment Caveat".
MAX_RUNTIME_SECONDS: int = 60
MAX_RUNTIME_SECONDS: int = 30
@dataclass(frozen=True, slots=True)
@ -172,19 +168,8 @@ def run_showcase(*, output_dir: Path, include_runtime_ms: bool = True) -> dict[s
deterministic_payload = {k: v for k, v in payload.items() if k != "total_runtime_ms"}
json_path.write_bytes(canonical_json(deterministic_payload))
# Budget is a soft case evaluated by evals/public_demo/runner.py
# (_case_runtime_under_budget). Hard-raising here aborted the lane
# before content cases could be recorded — a process bug. Opt into
# hard raise only via CORE_SHOWCASE_HARD_BUDGET=1 (e.g. product CLI
# demos that want fail-loud wall-clock). CORE_SHOWCASE_SKIP_BUDGET=1
# remains a full suppress for both soft and hard checks in callers.
_skip_budget = os.environ.get("CORE_SHOWCASE_SKIP_BUDGET") == "1"
_hard_budget = os.environ.get("CORE_SHOWCASE_HARD_BUDGET") == "1"
if (
_hard_budget
and not _skip_budget
and total_runtime_ms > MAX_RUNTIME_SECONDS * 1000
):
if total_runtime_ms > MAX_RUNTIME_SECONDS * 1000 and not _skip_budget:
raise DemoContractError(
f"showcase exceeded ADR-0099 runtime budget: "
f"{total_runtime_ms} ms > {MAX_RUNTIME_SECONDS * 1000} ms"

Some files were not shown because too many files have changed in this diff Show more