Merge pull request #136 from AssetOverflow/feat/adr-0123-lane-shape-symbolic-logic-fix
feat: ADR-0123 — re-map symbolic_logic to inference_shape (unblocks ADR-0122)
This commit is contained in:
commit
5e52cd4547
5 changed files with 139 additions and 27 deletions
|
|
@ -58,7 +58,7 @@ LANE_SHAPE_REGISTRY: dict[str, str] = {
|
|||
"cognition": "cognition_shape",
|
||||
"elementary_mathematics_ood": "accuracy_shape",
|
||||
"foundational_physics_ood": "accuracy_shape",
|
||||
"symbolic_logic": "symbolic_logic_shape",
|
||||
"symbolic_logic": "inference_shape",
|
||||
"hebrew_fluency": "accuracy_shape",
|
||||
"koine_greek_fluency": "accuracy_shape",
|
||||
"inference_closure": "inference_shape",
|
||||
|
|
@ -160,7 +160,6 @@ def _check_refusal_shape(lane_id: str, metrics: Mapping[str, Any]) -> tuple[bool
|
|||
SHAPE_CHECKERS: dict[str, Any] = {
|
||||
"cognition_shape": _check_cognition_shape,
|
||||
"accuracy_shape": _check_accuracy_shape,
|
||||
"symbolic_logic_shape": _check_accuracy_shape,
|
||||
"inference_shape": _check_inference_shape,
|
||||
"refusal_shape": _check_refusal_shape,
|
||||
}
|
||||
|
|
|
|||
71
docs/decisions/ADR-0123-symbolic-logic-shape-remap.md
Normal file
71
docs/decisions/ADR-0123-symbolic-logic-shape-remap.md
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
# ADR-0123 — `symbolic_logic` Lane-Shape Remap (ADR-0109 Amendment)
|
||||
|
||||
**Status:** Accepted
|
||||
**Date:** 2026-05-22
|
||||
**Author:** CORE agents + reviewers
|
||||
**Amends:** ADR-0109
|
||||
**Depends on:** ADR-0109, ADR-0122
|
||||
|
||||
---
|
||||
|
||||
## Context
|
||||
|
||||
Under [ADR-0109](file:///Users/kaizenpro/.gemini/antigravity/worktrees/core/fix-symbolic-logic-shape/docs/decisions/ADR-0109-lane-shape-aware-thresholds.md), threshold verification rules are lane-shape-aware, mapping specific lane IDs to defined metric shapes. [ADR-0109](file:///Users/kaizenpro/.gemini/antigravity/worktrees/core/fix-symbolic-logic-shape/docs/decisions/ADR-0109-lane-shape-aware-thresholds.md) mapped the `symbolic_logic` lane to `symbolic_logic_shape`, which internally dispatched to the accuracy-shape threshold checker (`_check_accuracy_shape`).
|
||||
|
||||
However, as documented in the deferred promotion of `systems_software` ([ADR-0122](file:///Users/kaizenpro/.gemini/antigravity/worktrees/core/fix-symbolic-logic-shape/docs/decisions/ADR-0122-systems-software-audit-passed-deferred.md)), the `symbolic_logic` lane output payload actually contains inference-style metrics (`all_pass_rate`, `replay_determinism`, and `overall_pass`) rather than accuracy-shape metrics (`accuracy` or `passed/total`). This mismatch caused the gate to fail closed with the error message: `lane 'symbolic_logic' missing accuracy (and no passed/total fallback)`.
|
||||
|
||||
This amendment corrects the mapping to unblock the `systems_software` promotion.
|
||||
|
||||
---
|
||||
|
||||
## Decision
|
||||
|
||||
Re-map the `symbolic_logic` lane to `inference_shape` within the `LANE_SHAPE_REGISTRY` in [core/capability/expert_demo.py](file:///Users/kaizenpro/.gemini/antigravity/worktrees/core/fix-symbolic-logic-shape/core/capability/expert_demo.py):
|
||||
|
||||
```python
|
||||
LANE_SHAPE_REGISTRY["symbolic_logic"] = "inference_shape"
|
||||
```
|
||||
|
||||
### Rationale
|
||||
The `symbolic_logic` lane validates propositional inference closure. Because it checks deterministic symbolic inferences rather than approximate/statistical accuracy scalars, it naturally produces the standard inference-style metrics:
|
||||
- `all_pass_rate`
|
||||
- `replay_determinism`
|
||||
- `overall_pass`
|
||||
|
||||
Mapping it to `inference_shape` aligns the contract verification logic with the lane's actual runtime evidence schema.
|
||||
|
||||
Additionally, because no other lane in the registry maps to `symbolic_logic_shape`, this shape checker is retired and removed from `SHAPE_CHECKERS` to preserve code cleanliness and avoid dead-shape drift.
|
||||
|
||||
---
|
||||
|
||||
## Invariants
|
||||
|
||||
### `inference_shape_thresholds_applied`
|
||||
The existing `inference_shape` thresholds defined in [ADR-0109](file:///Users/kaizenpro/.gemini/antigravity/worktrees/core/fix-symbolic-logic-shape/docs/decisions/ADR-0109-lane-shape-aware-thresholds.md) now govern `symbolic_logic` verification:
|
||||
- `all_pass_rate >= 0.95`
|
||||
- `replay_determinism == 1.0`
|
||||
- `overall_pass == True`
|
||||
|
||||
---
|
||||
|
||||
## Acceptance Evidence
|
||||
|
||||
Accepted when:
|
||||
- The registry mapping in [core/capability/expert_demo.py](file:///Users/kaizenpro/.gemini/antigravity/worktrees/core/fix-symbolic-logic-shape/core/capability/expert_demo.py) is amended to map `symbolic_logic` to `inference_shape`.
|
||||
- Unused `symbolic_logic_shape` is removed from `SHAPE_CHECKERS`.
|
||||
- A unit test `TestSymbolicLogicShapeGate` in [tests/test_lane_shape_thresholds.py](file:///Users/kaizenpro/.gemini/antigravity/worktrees/core/fix-symbolic-logic-shape/tests/test_lane_shape_thresholds.py) asserts that:
|
||||
- `resolve_lane_shape("symbolic_logic") == "inference_shape"`
|
||||
- `symbolic_logic` results carrying compliant inference-style metrics pass the gate successfully.
|
||||
|
||||
---
|
||||
|
||||
## Consequences
|
||||
|
||||
- The contract blocker for `systems_software` is resolved: the lane gate now evaluates `symbolic_logic` outputs under the correct metric schema.
|
||||
- The deferral in [ADR-0122](file:///Users/kaizenpro/.gemini/antigravity/worktrees/core/fix-symbolic-logic-shape/docs/decisions/ADR-0122-systems-software-audit-passed-deferred.md) can be resolved in a subsequent promotion attempt (likely ADR-0124) when a signed promotion claim is recorded.
|
||||
|
||||
---
|
||||
|
||||
## Out of Scope
|
||||
|
||||
- Actually signing the `systems_software` claim or updating the `audit_passed_claims` in `reviewers.yaml` (reserved for a follow-up promotion ADR).
|
||||
|
|
@ -37,26 +37,12 @@ class TestAdr0122Deferral:
|
|||
assert row["predicates"]["audit_passed"] is False
|
||||
|
||||
def test_named_blocker_matches_gate_reason(self) -> None:
|
||||
reviewer = Reviewer(
|
||||
reviewer_id="shay-j",
|
||||
display_name="Joshua Shay",
|
||||
role="primary",
|
||||
domains=("*",),
|
||||
review_scope=("pack", "proposal", "chain", "eval"),
|
||||
provenance="adr-0092:bootstrap:2026-05-21",
|
||||
)
|
||||
claim = ExpertDemoClaim(
|
||||
domain_id="systems_software",
|
||||
evidence_lanes=_SYSTEMS_LANES,
|
||||
evidence_revision="adr-0122:reviewed:2026-05-22",
|
||||
signed_by="shay-j",
|
||||
claim_digest="0" * 64,
|
||||
)
|
||||
registry = ReviewerRegistry(
|
||||
schema_version=1,
|
||||
reviewers=(reviewer,),
|
||||
expert_demo_claims=(claim,),
|
||||
)
|
||||
from pathlib import Path
|
||||
from core.capability.reviewers import load_reviewer_registry
|
||||
from core.capability.sources import LEDGER_SOURCES
|
||||
|
||||
repo_root = Path(__file__).resolve().parent.parent
|
||||
registry = load_reviewer_registry(repo_root / LEDGER_SOURCES.reviewers)
|
||||
lane_results = materialise_lane_results(_SYSTEMS_LANES, fetch_split=_fetch)
|
||||
|
||||
verdict = evaluate_expert_demo(
|
||||
|
|
@ -68,7 +54,4 @@ class TestAdr0122Deferral:
|
|||
)
|
||||
|
||||
assert verdict.passed is False
|
||||
assert (
|
||||
verdict.reason
|
||||
== "lane 'symbolic_logic' missing accuracy (and no passed/total fallback) (split=public)"
|
||||
)
|
||||
assert verdict.reason == "no audit_passed_claims entry for this domain"
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ _SHAPE_FIXTURES = {
|
|||
"inference_closure": _INFERENCE_METRICS,
|
||||
"elementary_mathematics_ood": _ACCURACY_METRICS,
|
||||
"foundational_physics_ood": _ACCURACY_METRICS,
|
||||
"symbolic_logic": _ACCURACY_METRICS,
|
||||
"symbolic_logic": _INFERENCE_METRICS,
|
||||
"hebrew_fluency": _ACCURACY_METRICS,
|
||||
"koine_greek_fluency": _ACCURACY_METRICS,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -162,3 +162,62 @@ class TestShapeThresholdValues:
|
|||
def test_inference_shape_minimums(self) -> None:
|
||||
assert ALL_PASS_RATE_MIN == 0.95
|
||||
assert REPLAY_DETERMINISM_MIN == 1.0
|
||||
|
||||
|
||||
class TestSymbolicLogicShapeGate:
|
||||
def test_symbolic_logic_resolves_to_inference_shape(self) -> None:
|
||||
assert resolve_lane_shape("symbolic_logic") == "inference_shape"
|
||||
|
||||
def test_symbolic_logic_with_inference_metrics_passes(self) -> None:
|
||||
reviewer = Reviewer(
|
||||
reviewer_id="shay-j",
|
||||
display_name="Joshua Shay",
|
||||
role="primary",
|
||||
domains=("*",),
|
||||
review_scope=("pack", "proposal", "chain", "eval"),
|
||||
provenance="adr-0092:bootstrap:2026-05-21",
|
||||
)
|
||||
|
||||
metrics = {
|
||||
"all_pass_rate": 0.98,
|
||||
"replay_determinism": 1.0,
|
||||
"overall_pass": True,
|
||||
}
|
||||
|
||||
lane_results = {
|
||||
"symbolic_logic": {
|
||||
"public": metrics,
|
||||
"holdout": metrics,
|
||||
}
|
||||
}
|
||||
|
||||
from core.capability.expert_demo import derive_evidence_digest
|
||||
digest = derive_evidence_digest(
|
||||
domain_id="systems_software",
|
||||
evidence_revision="rev1",
|
||||
evidence_lanes=("symbolic_logic",),
|
||||
lane_results=lane_results,
|
||||
)
|
||||
|
||||
claim = ExpertDemoClaim(
|
||||
domain_id="systems_software",
|
||||
evidence_lanes=("symbolic_logic",),
|
||||
evidence_revision="rev1",
|
||||
signed_by="shay-j",
|
||||
claim_digest=digest,
|
||||
)
|
||||
|
||||
registry = ReviewerRegistry(
|
||||
schema_version=1, reviewers=(reviewer,), expert_demo_claims=(claim,)
|
||||
)
|
||||
|
||||
verdict = evaluate_expert_demo(
|
||||
domain_id="systems_software",
|
||||
reasoning_capable=True,
|
||||
registry=registry,
|
||||
domain_lanes=("symbolic_logic",),
|
||||
lane_results=lane_results,
|
||||
)
|
||||
assert verdict.passed is True
|
||||
assert verdict.reason == "all audit-passed predicates satisfied"
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue