feat(semantic): compositional coordinate-address algebra + 23×6 bridge - #1199
feat(semantic): compositional coordinate-address algebra + 23×6 bridge#1199mdheller wants to merge 10 commits into
Conversation
…venance register Graded, non-commutative addressing algebra so semantic distance is COMPUTED from structure, not learned. Primitives trace to public-domain sources (Aristotle POT/ACT, Peirce FST/SND/TRD); layer discipline makes cross-abstraction matches structurally impossible. Ships Term/add/mul/distance, pushout/pullback + shared meet, bind_tiered, SemanticAddress (intension+extension+warrant), and pluralistic versioned Lexicons. 44 tests, every guard exercised both ways. Provenance register doubles as the clean-room warrant.
…h both ways Every agent declares itself on exactly eleven named axes (ten sefirot + Da'at). A vector with ten or twelve coordinates is REJECTED structurally, exactly one axis is primary, and the three middle-column axes (chesed/gevurah/tiferet) must be realised by pushout/pullback/meet respectively — so the middle column cannot be reimplemented ad hoc. JSON Schema is the registry face; the stdlib validator is the enforcement face for the two cross-field rules. 18 tests, all guards exercised on their refusal path.
Adds a complete, non-redundant governed-action frame (Tesniere's actants + case grammar: who, to what, for whom, by what and why, when, where, to what purpose, how), additive over v0.1. root+initiator required; the inventory is closed so an invented role is refused. skeleton() drops every role's surface text while keeping shape — the concrete linkability (G2) / twin de-identification lever. Universal linguistics, zero third-party IP. 14 tests, both ways.
Measures the quantity the KKO board never did: the rate at which an intro-level query is bound to a graduate-level topic. Over >=30 cases it FAILS if the binder crosses the abstraction anchor (mismatch_rate) AND FAILS as vacuous if it never admits a correct match or never abstains on a trap — a binder that abstains on everything scores a perfect zero and is worthless. bind_fn is a parameter so the gate is proven to catch a naive (anchor-ignoring) and a lazy (always-abstain) binder. Reproduces the intro-physics -> graduate-QFT trap explicitly.
…tice Two algebra deltas, each closing a place the kernel flinched under its own test. 1. Abstention becomes a first-class value BOTTOM (Gödel: incompleteness makes abstention structural, so it is carried, not smuggled as None). bind_tiered and pullback return it; meet absorbs it; distance to it is undefined; an abstaining SemanticAddress is well-formed but never grounded (is_grounded False even with an iri). The abstraction gate is made BOTTOM-aware. 2. The verdict lattice is DERIVED from VERDICT_CLEARS (what each verdict clears) by derive_verdict_order, not hand-authored — the one authored canon in the kernel, now removed. It raises unless the verdicts form a chain; a nested verdict extends the order with no second edit. Mach's economy + our own derived-not-authored rule turned on our own code. SPEC_VERSION 0.1.0 -> 0.2.0. 91 tests, both ways.
Lifts each intent row into a SemanticAddress, giving the flat grid the two things it
lacked and the kernel already had: a computed metric (same-column intents at distance
1, cross-column at 2 — nothing learned or curated per pair) and a layer (the meta row
conversation_objective is second-order, built one layer up out of an action address —
a fixed point in the grading, comparable only to its own order).
The columns are made explicit as {read:pullback, write:pushout} x {held=FST, world=SND,
store=TRD}. And the grid's headline finding goes structural: route a world:read query
with the sense intents absent and bind_tiered returns BOTTOM — the sense wiring gap
(thinnest column, 1/... on the primary grouping) surfaces as a first-class abstention,
not a silent mis-route. 7 tests. Encodes the roster as data; the canon stays in Noetica.
The #2 delta as its own spec: a coreflection L_n -> L_{n+1} with lift a full embedding, ground its retraction (BOTTOM on a leaf), ground∘lift = id and p ⊑ lift(ground(p)). Turns cross-layer relation from forbidden into warranted — distance_bridged is the only legal crossing, raw cross-layer distance still raises. Subsumes bind_tiered (admit c iff c ⊑ ground(anchor)) and makes Kant's schematism plural (many named morphisms, e.g. taxonomic vs mereological). Ships P1-P6 proof obligations, each with a refusal-path test; code to follow in its own change.
| from __future__ import annotations | ||
|
|
||
| from dataclasses import dataclass | ||
| from typing import Callable, List, Optional, Sequence |
|
|
||
| from __future__ import annotations | ||
|
|
||
| from typing import Dict, List, Optional |
|
|
||
| from __future__ import annotations | ||
|
|
||
| from typing import Dict, List, Optional, Tuple |
| from tools.semantic_algebra import ( | ||
| ACT, | ||
| BOTTOM, | ||
| FST, | ||
| NIL, | ||
| POT, | ||
| PRIMITIVES, | ||
| SND, | ||
| TRD, | ||
| SemanticAddress, | ||
| Term, | ||
| TermSet, | ||
| add, | ||
| bind_tiered, | ||
| distance, | ||
| mul, | ||
| prim, | ||
| ) |
|
|
||
| from __future__ import annotations | ||
|
|
||
| import copy |
There was a problem hiding this comment.
Pull request overview
This PR introduces a stdlib-only “semantic address” kernel (tools/semantic_algebra.py) and related contracts/validators/tests, plus a bridge (tools/intent_address.py) that lifts the existing 23×6 intent grid into the algebra to gain a structural metric, explicit layering, and first-class abstention (BOTTOM).
Changes:
- Added a graded, non-commutative term algebra with structural distance, tiered grounding, dual operators (pullback/pushout), an absorbing abstention value (
BOTTOM), and a derived verdict lattice. - Added the 23×6 intent-grid bridge that assigns each intent row a
SemanticAddressand provides structural routing/distance utilities. - Added contracts, examples, validators, and extensive “both ways” test suites for the algebra, deltas, intent bridge, actants frame, and abstraction-level gate.
Reviewed changes
Copilot reviewed 17 out of 17 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| tools/semantic_algebra.py | Core semantic-address algebra (terms, distance, tiered binding, abstention, verdict lattice derivation, lexicons). |
| tools/intent_address.py | Bridge from the 23×6 intent grid into the algebra; adds intent addresses, routing, distance, and fill metrics. |
| tools/boundary_transition_actants.py | Validator + skeleton for BoundaryTransition v0.2 actantial frame. |
| tools/agent_coordinate_vector.py | Validator for AgentCoordinateVector v0.1 with cross-field/operator-axis coherence. |
| tools/abstraction_level_gate.py | Gate that measures abstraction-level mismatch rate against a pluggable binder. |
| tools/tests/test_semantic_algebra.py | Main algebra conformance tests (construction, operators, distance, tiered binding, addresses, lexicons). |
| tools/tests/test_semantic_algebra_deltas.py | Tests for BOTTOM-as-abstention and derived verdict lattice ordering. |
| tools/tests/test_intent_address.py | Tests for intent-grid bridge (layering, metric, routing, sense-gap abstention, column fill). |
| tools/tests/test_boundary_transition_actants.py | Tests for actantial frame validation + skeleton + shipped example validation. |
| tools/tests/test_agent_coordinate_vector.py | Tests for AgentCoordinateVector v0.1 validation rules and shipped example validation. |
| tools/tests/test_abstraction_level_gate.py | Tests demonstrating the gate passing real binder and failing naive/lazy binders. |
| docs/SEMANTIC_LAYER_ADJUNCTION.md | Design note/spec for a future lift ⊣ ground layer-bridging adjunction (no code yet). |
| docs/SEMANTIC_COORDINATE_ALGEBRA.md | Provenance register + conformance notes backing the kernel’s primitives and rules. |
| contracts/BoundaryTransition.v0.2.json | JSON Schema for BoundaryTransition v0.2 including closed actants inventory. |
| contracts/AgentCoordinateVector.v0.1.json | JSON Schema for AgentCoordinateVector v0.1 (11 axes, primary, operator metadata). |
| contracts/examples/boundary-transition-v0.2-ai-invocation.example.json | Example instance for BoundaryTransition v0.2 (includes actants frame). |
| contracts/examples/agent-coordinate-vector-michael-agent.example.json | Example instance for AgentCoordinateVector v0.1. |
Suppressed comments (1)
tools/intent_address.py:182
column_fill()assumes everySemanticAddresshas a non-abstainingTerm. If any address hasterm is BOTTOM, accessingaddr.term.layer/roles()will fail. Skip abstaining terms explicitly so the helper can operate on partial/abstaining address sets safely.
for name, addr in addresses.items():
if name == META_ROW or addr.term.layer != 2:
continue
ground = addr.term.roles()["ground"]
col = anchors.get(ground.code())
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| def route(query_column: str, addresses: Dict[str, SemanticAddress]) -> "Term | object": | ||
| """Ground a by-column query to an intent under that column, or abstain. | ||
|
|
||
| Returns the admitted intent's term, or BOTTOM when the column has no intent in | ||
| `addresses` — which is exactly what makes the `sense` wiring gap show up as an | ||
| honest abstention rather than a mis-route. | ||
| """ | ||
| topic_terms = [ | ||
| addr.term for name, addr in addresses.items() | ||
| if name != META_ROW and addr.term.layer == 2 # layer-2 topic rows | ||
| ] | ||
| upper = add(*[column_anchor(c) for c in COLUMNS]) | ||
| lower = add(*topic_terms) | ||
| return bind_tiered(column_anchor(query_column), upper, lower) |
| def column_anchor(column: str) -> Term: | ||
| """The layer-1 anchor for a column: substrate primitive x polarity marker.""" | ||
| substrate, polarity = COLUMNS[column] | ||
| return mul(prim(SUBSTRATE_PRIM[substrate]), prim(POLARITY_PRIM[polarity])) |
| # --------------------------------------------------------------------------- # | ||
|
|
||
|
|
||
| def distance(a: Term, b: Term) -> int: |
Implements the #2 delta from the design note. lift generalizes (t -> one layer up as the ground of a neutral product), ground specializes (BOTTOM on a leaf). A coreflection: ground(lift(t)) == t exactly, refines(p, lift(ground(p))) always. refines is the ⊑ relation (neutral = top). distance_bridged is the ONLY legal cross-layer comparison (adjacent-only); raw cross-layer distance still raises. P1-P6 proof obligations, each with its refusal path. Kant's schematism, now plural and typed.
…tive schemas Self-review found two real defects, both fixed with teeth: 1. Clean-room LEAK: docs/SEMANTIC_COORDINATE_ALGEBRA.md named a third-party metalanguage twice in a tracked repo file, contradicting its own posture. Scrubbed to generic wording; and mechanized so it can't recur — tools/check_cleanroom.py scans the framework files and exits non-zero on any third-party mark (self-excluding, proven to bite on a synthetic leak). 2. DECORATIVE schemas: the JSON-Schema contracts were shipped but nothing loaded them. test_contract_schemas.py now validates each schema is well-formed, each example conforms, and a malformed doc is rejected AT THE SCHEMA (ten/twelve axes, missing actants, bad enum). Matches the estate's jsonschema convention. 114 tests total, all green; clean-room CLI verified clean over the real tree.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 21 out of 21 changed files in this pull request and generated no new comments.
Suppressed comments (6)
tools/semantic_algebra.py:125
Term.__post_init__enforces only the leaf-vs-product split, but does not enforce the stated product invariants (differentia/mode present and same-layer). BecauseTermis public, callers can construct invalid products (e.g.,Term(ground=prim(POT))) that will later crash incode()/roles()or miscomputelayerwithout a clear error. Consider validating product completeness and operand layers here so the type is internally consistent regardless of construction path.
def __post_init__(self) -> None:
is_leaf = self.primitive is not None
is_product = self.ground is not None
if is_leaf == is_product:
raise ValueError("a Term is either a primitive or a product, not both/neither")
if is_leaf and self.primitive not in PRIMITIVES:
raise ValueError(f"unknown primitive {self.primitive!r}")
tools/intent_address.py:133
build_intent_addresses()assigns disambiguators by iteratingsorted(INTENT_PRIMARY.items()). This makes term codes (and therefore semantic addresses) unstable: adding a new intent whose name sorts earlier will renumber every later intent’s disambiguator, changing existing addresses unexpectedly. If these addresses are persisted or compared across versions, that becomes a breaking change for a non-semantic edit.
for i, (name, column) in enumerate(sorted(INTENT_PRIMARY.items())):
ground = _META_COLUMN_ANCHOR if column == "meta" else column_anchor(column)
term = mul(ground, _DISAMBIGUATORS[i])
tools/check_cleanroom.py:12
- The module docstring says the guard and its test are “never scanned”, but
scan_paths()only self-excludescheck_cleanroom.pyby filename. Iftools/tests/test_check_cleanroom.pyis passed explicitly (or the repo is scanned wholesale), the guard will flag its own fixtures and fail, contradicting the stated self-exclusion behavior.
Self-exclusion: this file and its test necessarily contain the forbidden tokens (the
patterns they scan for, and the fixtures that prove they bite), so they are never
scanned. A scanner that flags itself is broken — see the estate rule that a
docs/SEMANTIC_LAYER_ADJUNCTION.md:6
- This design note still claims “Status: DESIGN (code to follow)” and that it “does not ship code”, but this PR now adds
lift,ground,refines, anddistance_bridgedplus proof-obligation tests. The status/description is now materially outdated and could confuse readers about where the implementation lives.
Status: DESIGN (code to follow) · Scope: an addition to `tools/semantic_algebra.py`
Motivation: Kant's schematism, made plural and principled. This note is spec + proof
obligations; it deliberately does not ship code, because an adjunction earns its keep
only with a both-ways proof and that deserves its own change.
docs/SEMANTIC_COORDINATE_ALGEBRA.md:3
- The status line says “v0.1”, but the implementation sets
SPEC_VERSION = "0.2.0"intools/semantic_algebra.py. If these versions are meant to track one another, the doc is now inconsistent with the shipped spec version.
Status: v0.1 · stdlib-only kernel in `tools/semantic_algebra.py`
tools/semantic_algebra.py:355
pullback()doesn’t validate thatconstraintkeys are valid roles. If a caller passes an unknown key,cell.roles()[role]will raise aKeyErrormid-comprehension, which is a leaky/unclear failure mode for a public API. Consider validatingconstraintkeys up front and raising aValueErrorwith a helpful message.
def pullback(candidates: TermSet, constraint: Dict[str, Term]) -> "TermSet | Abstain":
"""LIMIT / restrict — keep only the cells agreeing with `constraint` on each role.
The restrictive operator. Returns BOTTOM when the restriction is total: a
first-class abstention the caller must reconcile, not an empty-but-fine result
and not a smuggled ``None``.
"""
kept = set()
for cell in candidates.terms:
if cell.is_leaf:
continue
if all(cell.roles()[role] == want for role, want in constraint.items()):
kept.add(cell)
return TermSet(frozenset(kept)) if kept else BOTTOM
…theory (proof, both ways) Turns the two tightest doctrine claims into passing tests, not prose: 1. Edgeworth supermodularity (manuscript eq 21) IS the lattice meet condition — the cross-difference equals g(a∨b)+g(a∧b)−g(a)−g(b) with ∧=min, the same min-on-a-chain that semantic_algebra.meet implements. Shown equal for arbitrary cells. 2. The per-cell clipping projection (eq 57) IS a pullback onto the supermodular half-space: idempotent on feasible cells, lands infeasible cells exactly on the boundary by the minimal L2 move; dual projection for substitutability (eq 23). 11 tests both ways; spectral_grounding.py added to the clean-room manifest.
|
|
||
| from typing import Dict, Tuple | ||
|
|
||
| from tools.semantic_algebra import VERDICT_ORDER, meet |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 23 out of 23 changed files in this pull request and generated no new comments.
Suppressed comments (2)
tools/intent_address.py:162
route()will raise aValueErrorwhenaddressescontains no layer-2 topic rows becauseadd(*topic_terms)is illegal for an empty list (TermSet must be non-empty). It also raises aKeyErrorfor an unknownquery_column. Since the docstring describes abstention (BOTTOM) as the outcome for an unrouteable query, it would be safer forroute()to validatequery_columnand returnBOTTOMwhen there are no candidate topic terms (instead of throwing). Also, the return annotation can be narrowed fromTerm | objecttoTerm | Abstainto match the actual outcomes (bind_tiered/BOTTOM).
def route(query_column: str, addresses: Dict[str, SemanticAddress]) -> "Term | object":
"""Ground a by-column query to an intent under that column, or abstain.
Returns the admitted intent's term, or BOTTOM when the column has no intent in
`addresses` — which is exactly what makes the `sense` wiring gap show up as an
tools/semantic_algebra.py:126
Term.__post_init__does not enforce the invariants implied by the class docs: a primitive term can still be constructed withdifferentia/modeset, and a product term can be constructed withdifferentiaormodemissing (or at a different layer) if callers instantiateTerm(...)directly. That can later crash inroles()/code()/distance()viaNone.code()or mixed-layer recursion. Consider validating product/leaf shape (and operand layers) here so invalid terms are rejected at construction, not at use sites.
def __post_init__(self) -> None:
is_leaf = self.primitive is not None
is_product = self.ground is not None
if is_leaf == is_product:
raise ValueError("a Term is either a primitive or a product, not both/neither")
|
Closing in favor of the ProCybernetica sovereign lib. The kernel developed on this branch was extracted and MERGED into ProCybernetica ( The review findings raised here (route abstaining-address guard, column_anchor ValueError, distance signature, unused imports) were applied to the live kernel in ProCybernetica #116 — not to this soon-to-be-redundant copy. Nothing is lost: the algebra, the S0/S4/S5 work, the BOTTOM+derived-lattice deltas, the lift⊣ground adjunction, the spectral-grounding proof, and the clean-room guard all live on ProCybernetica |
What
A graded, non-commutative semantic-address algebra so that semantic distance is computed from structure rather than learned from a corpus — plus the first contracts and the bridge that put it to work. Every primitive traces to a public-domain source (Aristotle's potentiality/actuality, Peirce's Firstness/Secondness/Thirdness); the provenance register in
docs/SEMANTIC_COORDINATE_ALGEBRA.mdis the warrant.Commits
Term/add/mul/distance,pushout/pullback+ one sharedmeet,bind_tiered,SemanticAddress(intension + extension + warrant), pluralisticLexiconsAgentCoordinateVector.v0.1BoundaryTransition.v0.2skeleton()de-identification leverVERDICT_ORDERderived fromVERDICT_CLEARS, not authoredsensegap becomes a first-class ⊥lift ⊣ groundspec (code to follow)Why it's trustworthy
Scope / notes
lift ⊣ groundimplementation are follow-ups.🤖 Generated with Claude Code