Merge pull request #697 from AssetOverflow/feat/demo-authority-strength
fix(demo): harden #690 epistemic truth-state — sealed corpus + entailment-decided inference
This commit is contained in:
commit
c6d0e2a920
21 changed files with 852 additions and 176 deletions
9
.gitignore
vendored
9
.gitignore
vendored
|
|
@ -51,3 +51,12 @@ teaching/math_proposals/proposals.jsonl
|
|||
engine_state/manifest.json
|
||||
engine_state/recognizers.jsonl
|
||||
engine_state/discovery_candidates.jsonl
|
||||
|
||||
# Private outreach / personal packet — never tracked
|
||||
01_Anthropic/
|
||||
|
||||
# Agent working directories
|
||||
.agents/
|
||||
|
||||
# Cowork/Claude tooling artifacts
|
||||
skills-lock.json
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
This demo proves one narrow boundary:
|
||||
|
||||
```text
|
||||
A model-style proposer submits a claim, an evidence bundle, and an optional
|
||||
bounded-inference block.
|
||||
A model-style proposer submits a claim, sealed evidence references, and an
|
||||
optional bounded-inference block.
|
||||
CORE alone assigns the typed epistemic state.
|
||||
The output is a deterministic, replayable evidence artifact.
|
||||
The proposer never controls its own truth-state.
|
||||
|
|
@ -23,19 +23,37 @@ state is typed
|
|||
|
||||
* A model-style proposer can submit a claim without gaining authority over its
|
||||
epistemic standing.
|
||||
* The proposer supplies evidence references only. CORE resolves those references
|
||||
against the sealed local corpus in
|
||||
[`evidence_corpus.json`](evidence_corpus.json), requiring a matching
|
||||
`content_sha256` before any evidence can count.
|
||||
* CORE alone assigns the typed state, drawn from the canonical taxonomy in
|
||||
[`core/epistemic_state.py`](../../core/epistemic_state.py) — `verified`,
|
||||
`evidenced`, `inferred`, `undetermined`, `scope_boundary`. There is no
|
||||
parallel enum.
|
||||
`evidenced`, `inferred`, `contradicted`, `undetermined`, `scope_boundary`.
|
||||
There is no parallel enum.
|
||||
* CORE derives `normative_clearance`, the `evidence_ledger`, the
|
||||
`authority_path`, and a fresh `trace_hash` itself.
|
||||
`authority_path`, and a fresh `trace_hash` itself. The corpus seal
|
||||
(`corpus_sha256`) is pinned into every evaluated trace.
|
||||
* Any proposer-supplied `proposed_state` or `trace_hash` is recorded as ignored
|
||||
and never read by the decision path.
|
||||
* Invalid payloads fail at the typed boundary *before* any state evaluation
|
||||
runs.
|
||||
* `verified` requires two or more independent evidence records that explicitly
|
||||
match the claim's subject and predicate — corroboration the proposer cannot
|
||||
fabricate through the schema.
|
||||
* `verified` requires two or more corpus records that explicitly match the
|
||||
claim's subject and predicate and come from distinct provenance roots —
|
||||
corroboration the proposer cannot fabricate through the request schema.
|
||||
* `inferred` is decided by a real entailment proof, not by reference counting.
|
||||
The cited premises (fact records contribute their `subject__predicate` atom;
|
||||
rule records their committed formula) must *propositionally entail* the
|
||||
claim's atom under
|
||||
[`generate/proof_chain/entail.py`](../../generate/proof_chain/entail.py) —
|
||||
the sound-and-complete ROBDD decision procedure — cross-checked against the
|
||||
independent truth-table oracle in
|
||||
[`evals/deductive_logic/oracle.py`](../../evals/deductive_logic/oracle.py)
|
||||
(no shared code). The ROBDD proof keys and the oracle verdict are both in
|
||||
the trace; if the two procedures ever disagreed, the demo refuses outright.
|
||||
Citing records that merely *exist* yields `undetermined`, never `inferred` —
|
||||
the committed scenario `unrelated-premise-still-undetermined` exercises
|
||||
exactly that attack.
|
||||
|
||||
## What this does not prove
|
||||
|
||||
|
|
@ -47,6 +65,9 @@ state is typed
|
|||
a claim and makes no safety guarantee.
|
||||
* It does not call a network, a model API, a subprocess, or any side-effecting
|
||||
tool. It evaluates JSON and returns JSON.
|
||||
* The entailment leg is propositional only (atoms are `subject__predicate`
|
||||
pairs); quantified or predicate-logic structure is out of regime and refuses
|
||||
upstream in the engine.
|
||||
* It does not claim broader epistemic coverage than the small local envelope and
|
||||
the deterministic rules encoded in `authority.py`.
|
||||
|
||||
|
|
@ -74,18 +95,27 @@ Each layer keeps the same doctrine: a model-style proposer contributes typed
|
|||
data, CORE alone decides, and the decision is a deterministic trace artifact
|
||||
with no proposer-held authority and no execution path.
|
||||
|
||||
## The six scenarios
|
||||
## The seven scenarios
|
||||
|
||||
* `verified-supported-claim` — two independent matching records → `verified`,
|
||||
`verified_by_matching_evidence` (clearance `unassessable`).
|
||||
* `verified-supported-claim` — two matching corpus records with distinct
|
||||
provenance roots → `verified`, `verified_by_matching_evidence` (clearance
|
||||
`unassessable`).
|
||||
* `evidenced-but-not-verified-claim` — one supporting record → `evidenced`,
|
||||
`evidence_present_but_not_verifying`.
|
||||
* `inferred-from-bounded-evidence` — claim follows from resolved premises →
|
||||
`inferred`, `bounded_inference_from_evidence`, with `inference_basis` IDs.
|
||||
* `inferred-from-bounded-evidence` — two fact premises plus a ratified rule
|
||||
record propositionally entail the claim's atom → `inferred`,
|
||||
`entailed_from_resolved_premises`, with the ROBDD entailment trace
|
||||
(`entailment_check_key: "T"`), the independent oracle verdict, and
|
||||
`inference_basis` IDs.
|
||||
* `unrelated-premise-still-undetermined` — a claim with no support citing a
|
||||
resolvable but logically unrelated record as a premise → the engine decides
|
||||
`unknown`, the state is `undetermined`. `inferred` cannot be minted by
|
||||
citing records that merely exist.
|
||||
* `undetermined-insufficient-evidence` — no relevant evidence → `undetermined`,
|
||||
`insufficient_evidence`, with an explicit `question`.
|
||||
* `refused-outside-scope` — claim declared outside the local envelope →
|
||||
status `refused`, `scope_boundary`, `outside_epistemic_envelope`.
|
||||
status `refused`, `scope_boundary`, `outside_epistemic_envelope`; the corpus
|
||||
is never consulted.
|
||||
* `invalid-state-smuggling-attempt` — root-level `assigned_state` / `status` /
|
||||
`evidence_ledger` / `authority_path` / `trace_hash` injection → status
|
||||
`invalid`, `authority_evaluated: false`, every smuggled property listed in
|
||||
|
|
@ -94,15 +124,22 @@ with no proposer-held authority and no execution path.
|
|||
## Honesty ledger
|
||||
|
||||
* Real: closed recursive schema validation, canonical-enum state assignment via
|
||||
`core.epistemic_state`, deterministic trace hashing over the response minus
|
||||
`trace_hash`, evidence-ledger derivation, expected-artifact pinning,
|
||||
double-run byte-identical determinism, output-directory hardening.
|
||||
`core.epistemic_state`, sealed-corpus evidence resolution by content hash,
|
||||
sound-and-complete ROBDD entailment with independent-oracle cross-check on
|
||||
the inference leg, deterministic trace hashing over the response minus
|
||||
`trace_hash`, corpus seal pinning, evidence-ledger derivation,
|
||||
expected-artifact pinning, double-run byte-identical determinism,
|
||||
output-directory hardening.
|
||||
* Simulated: the proposer side is static fixture data standing in for a
|
||||
model-style proposer; the evidence bundle is hand-authored, not retrieved from
|
||||
the live vault.
|
||||
model-style proposer; the evidence corpus is committed local fixture evidence,
|
||||
not retrieved from the live vault.
|
||||
* Honest non-claim: `normative_clearance` is `unassessable` on every
|
||||
non-invalid output, including `verified`, because this demo runs no
|
||||
safety/ethics verdict pass and therefore has no basis to clear anything.
|
||||
* Defensive path: the `entailment_oracle_disagreement` refusal exists and is
|
||||
tested (by forcing a fake oracle verdict in tests); it has never fired on
|
||||
real input and is expected never to — both procedures are sound and complete
|
||||
over the propositional regime.
|
||||
* Not claimed: runtime integration, serving integration, real evidence
|
||||
retrieval, a safety guarantee, or any coverage beyond this local envelope.
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,19 @@
|
|||
"""Local deterministic epistemic-state authority substrate for the demo.
|
||||
|
||||
A model-style proposer submits a claim, an evidence bundle, and (optionally) a
|
||||
bounded-inference block. The proposer contributes *data only*. CORE alone:
|
||||
A model-style proposer submits a claim, sealed evidence references, and
|
||||
(optionally) a bounded-inference block. The proposer contributes *references only*
|
||||
for evidence; CORE resolves those references against a sealed local corpus. CORE
|
||||
alone:
|
||||
|
||||
* validates a closed payload,
|
||||
* resolves evidence references by committed content hash,
|
||||
* derives support and provenance independence from the committed record bodies
|
||||
(never from proposer-supplied labels — the schema rejects them),
|
||||
* decides the bounded-inference leg with the real propositional entailment
|
||||
engine (:func:`generate.proof_chain.entail.evaluate_entailment_with_trace`,
|
||||
the sound-and-complete ROBDD decision procedure) cross-checked against the
|
||||
independent truth-table oracle
|
||||
(:func:`evals.deductive_logic.oracle.oracle_entailment`),
|
||||
* assigns the typed epistemic state drawn from the canonical taxonomy in
|
||||
:mod:`core.epistemic_state` (never a parallel enum),
|
||||
* derives normative clearance,
|
||||
|
|
@ -11,7 +21,10 @@ bounded-inference block. The proposer contributes *data only*. CORE alone:
|
|||
* regenerates a deterministic trace hash.
|
||||
|
||||
The proposer cannot set ``assigned_state``, ``status``, ``trace_hash``,
|
||||
``authority_path``, the evidence ledger, or ``normative_clearance``. Any
|
||||
``authority_path``, the evidence ledger, or ``normative_clearance`` — and it
|
||||
cannot mint them indirectly: ``inferred`` is assigned only when the cited,
|
||||
resolved premises *propositionally entail* the claim's atom, so citing
|
||||
unrelated records as premises yields ``undetermined``, not ``inferred``. Any
|
||||
proposer-supplied ``proposed_state`` / ``trace_hash`` is recorded as ignored
|
||||
and never read by the decision path. Nothing here executes a side effect.
|
||||
"""
|
||||
|
|
@ -21,6 +34,7 @@ from __future__ import annotations
|
|||
import hashlib
|
||||
import json
|
||||
import re
|
||||
from dataclasses import dataclass
|
||||
from functools import lru_cache
|
||||
from pathlib import Path
|
||||
from typing import Any, Final
|
||||
|
|
@ -31,10 +45,13 @@ from core.epistemic_state import (
|
|||
coerce_epistemic_state,
|
||||
coerce_normative_clearance,
|
||||
)
|
||||
from evals.deductive_logic.oracle import oracle_entailment
|
||||
from generate.proof_chain.entail import Entailment, evaluate_entailment_with_trace
|
||||
|
||||
TOOL_NAME: Final[str] = "core.epistemic_truth_state.review"
|
||||
_HERE: Final[Path] = Path(__file__).resolve().parent
|
||||
SCHEMA_PATH: Final[Path] = _HERE / "schema.json"
|
||||
EVIDENCE_CORPUS_PATH: Final[Path] = _HERE / "evidence_corpus.json"
|
||||
|
||||
# The local epistemic authority envelope: only claims declared inside these
|
||||
# domains are evaluated. Anything else is refused as outside scope rather than
|
||||
|
|
@ -42,8 +59,11 @@ SCHEMA_PATH: Final[Path] = _HERE / "schema.json"
|
|||
ENVELOPE_DOMAINS: Final[frozenset[str]] = frozenset({"demo.local_factual"})
|
||||
|
||||
_ROOT_AUTHORITY: Final[str] = "demos.epistemic_truth_state.authority.validate_payload"
|
||||
_CORPUS_AUTHORITY: Final[str] = "demos.epistemic_truth_state.authority.resolve_evidence_refs"
|
||||
_ASSIGN_AUTHORITY: Final[str] = "demos.epistemic_truth_state.authority.assign_epistemic_state"
|
||||
_ENVELOPE_AUTHORITY: Final[str] = "demo_epistemic_truth_state_envelope(local-v1)"
|
||||
_ENTAIL_AUTHORITY: Final[str] = "generate.proof_chain.entail.evaluate_entailment_with_trace"
|
||||
_ORACLE_AUTHORITY: Final[str] = "evals.deductive_logic.oracle.oracle_entailment"
|
||||
_TAXONOMY_AUTHORITY: Final[str] = "core.epistemic_state.coerce_epistemic_state"
|
||||
|
||||
_SUPPORTED_SCHEMA_KEYS: Final[frozenset[str]] = frozenset(
|
||||
|
|
@ -75,6 +95,40 @@ def load_schema() -> dict[str, Any]:
|
|||
return json.loads(SCHEMA_PATH.read_text(encoding="utf-8"))
|
||||
|
||||
|
||||
@lru_cache(maxsize=1)
|
||||
def load_evidence_corpus() -> dict[str, dict[str, Any]]:
|
||||
raw = json.loads(EVIDENCE_CORPUS_PATH.read_text(encoding="utf-8"))
|
||||
records = raw.get("records")
|
||||
if not isinstance(records, list):
|
||||
raise ValueError("evidence corpus must contain a records array")
|
||||
by_id: dict[str, dict[str, Any]] = {}
|
||||
for record in records:
|
||||
if not isinstance(record, dict):
|
||||
raise ValueError("evidence corpus records must be objects")
|
||||
evidence_id = record.get("evidence_id")
|
||||
if not isinstance(evidence_id, str):
|
||||
raise ValueError("evidence corpus record missing evidence_id")
|
||||
if evidence_id in by_id:
|
||||
raise ValueError(f"duplicate evidence_id {evidence_id!r}")
|
||||
by_id[evidence_id] = dict(record)
|
||||
return by_id
|
||||
|
||||
|
||||
def _evidence_record_hash(record: dict[str, Any]) -> str:
|
||||
return _hash_text(_canonical(record))
|
||||
|
||||
|
||||
@lru_cache(maxsize=1)
|
||||
def corpus_file_sha256() -> str:
|
||||
"""Hash of the committed corpus file bytes — the seal pinned into traces."""
|
||||
return _hash_text(EVIDENCE_CORPUS_PATH.read_text(encoding="utf-8"))
|
||||
|
||||
|
||||
@lru_cache(maxsize=1)
|
||||
def corpus_identifier() -> str:
|
||||
return str(json.loads(EVIDENCE_CORPUS_PATH.read_text(encoding="utf-8"))["corpus_id"])
|
||||
|
||||
|
||||
def _clip(value: object) -> str:
|
||||
rendered = repr(value)
|
||||
return rendered if len(rendered) <= 80 else rendered[:79] + "…"
|
||||
|
|
@ -230,6 +284,29 @@ def _invalid_response(payload: Any, errors: tuple[str, ...]) -> dict[str, Any]:
|
|||
)
|
||||
|
||||
|
||||
def _invalid_evidence_response(payload: dict[str, Any], errors: tuple[str, ...]) -> dict[str, Any]:
|
||||
return _finalize(
|
||||
{
|
||||
"tool": TOOL_NAME,
|
||||
"status": "invalid",
|
||||
"request_id": payload["request_id"],
|
||||
"scenario_id": payload["scenario_id"],
|
||||
"authority_path": [_ROOT_AUTHORITY, _CORPUS_AUTHORITY],
|
||||
"decision_reason": "invalid_evidence_reference",
|
||||
"assigned_state": None,
|
||||
"normative_clearance": None,
|
||||
"evidence_ledger": [],
|
||||
"trace_summary": {
|
||||
"authority_evaluated": False,
|
||||
"evidence_reference_errors": list(errors),
|
||||
"proposer_trace_hash_ignored": _proposer_trace_hash_present(payload),
|
||||
"proposer_state_ignored": _proposer_state_present(payload),
|
||||
},
|
||||
"invalid_reason": "; ".join(errors),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def _claim_fingerprint(payload: dict[str, Any]) -> str:
|
||||
proposer = payload["proposer"]
|
||||
digest_input = {
|
||||
|
|
@ -245,43 +322,174 @@ def _claim_fingerprint(payload: dict[str, Any]) -> str:
|
|||
return _hash_text(_canonical(digest_input))
|
||||
|
||||
|
||||
def resolve_evidence_refs(refs: list[dict[str, Any]]) -> tuple[list[dict[str, Any]], tuple[str, ...]]:
|
||||
"""Resolve proposer-supplied refs against the sealed local evidence corpus."""
|
||||
corpus = load_evidence_corpus()
|
||||
resolved: list[dict[str, Any]] = []
|
||||
errors: list[str] = []
|
||||
seen: set[str] = set()
|
||||
for ref in refs:
|
||||
evidence_id = ref["evidence_id"]
|
||||
if evidence_id in seen:
|
||||
errors.append(f"duplicate evidence reference {evidence_id!r}")
|
||||
continue
|
||||
seen.add(evidence_id)
|
||||
record = corpus.get(evidence_id)
|
||||
if record is None:
|
||||
errors.append(f"unknown evidence reference {evidence_id!r}")
|
||||
continue
|
||||
expected_hash = _evidence_record_hash(record)
|
||||
if ref["content_sha256"] != expected_hash:
|
||||
errors.append(f"content hash mismatch for evidence reference {evidence_id!r}")
|
||||
continue
|
||||
# Hand out a copy: the corpus cache must stay immutable in-process.
|
||||
resolved.append(dict(record))
|
||||
return resolved, tuple(errors)
|
||||
|
||||
|
||||
def _matching_evidence(claim: dict[str, Any], evidence: list[dict[str, Any]]) -> list[dict[str, Any]]:
|
||||
"""Evidence records that explicitly support the claim subject and predicate."""
|
||||
"""Corpus records that match the claim subject and predicate."""
|
||||
subject = claim["subject"]
|
||||
predicate = claim["predicate"]
|
||||
return [
|
||||
record
|
||||
for record in evidence
|
||||
if bool(record.get("supports"))
|
||||
if record.get("source_kind") != "premise"
|
||||
and record.get("subject") == subject
|
||||
and record.get("predicate") == predicate
|
||||
]
|
||||
|
||||
|
||||
def _resolved_inference_basis(payload: dict[str, Any]) -> list[str] | None:
|
||||
"""Return sorted premise IDs iff an inference block resolves fully, else None."""
|
||||
def _independent_evidence(evidence: list[dict[str, Any]]) -> list[dict[str, Any]]:
|
||||
by_root: dict[str, dict[str, Any]] = {}
|
||||
for record in evidence:
|
||||
root = record["provenance_root"]
|
||||
by_root.setdefault(root, record)
|
||||
return list(by_root.values())
|
||||
|
||||
|
||||
def _claim_atom(claim: dict[str, Any]) -> str:
|
||||
"""The propositional atom the claim asserts (schema guarantees snake_case
|
||||
parts, so the derivation is total)."""
|
||||
return f"{claim['subject']}__{claim['predicate']}"
|
||||
|
||||
|
||||
def _premise_formula(record: dict[str, Any]) -> str:
|
||||
"""The propositional contribution of one resolved corpus record: a rule
|
||||
record contributes its committed formula, a fact record its atom."""
|
||||
formula = record.get("formula")
|
||||
if isinstance(formula, str) and formula:
|
||||
return formula
|
||||
return f"{record['subject']}__{record['predicate']}"
|
||||
|
||||
|
||||
@dataclass(frozen=True, slots=True)
|
||||
class _InferenceReport:
|
||||
"""What the bounded-inference leg did, as inert trace data."""
|
||||
|
||||
consulted: bool
|
||||
detail: str
|
||||
premise_ids: tuple[str, ...] = ()
|
||||
outcome: str | None = None
|
||||
reason: str | None = None
|
||||
oracle_verdict: str | None = None
|
||||
agreement: bool | None = None
|
||||
entailment: dict[str, Any] | None = None
|
||||
|
||||
def to_trace_dict(self) -> dict[str, Any]:
|
||||
summary: dict[str, Any] = {"consulted": self.consulted, "detail": self.detail}
|
||||
if self.consulted:
|
||||
summary.update(
|
||||
{
|
||||
"premise_ids": list(self.premise_ids),
|
||||
"outcome": self.outcome,
|
||||
"reason": self.reason,
|
||||
"oracle_verdict": self.oracle_verdict,
|
||||
"engine_oracle_agreement": self.agreement,
|
||||
"entailment_trace": self.entailment,
|
||||
}
|
||||
)
|
||||
return summary
|
||||
|
||||
|
||||
_INFERENCE_NOT_PRESENT: Final[_InferenceReport] = _InferenceReport(
|
||||
consulted=False, detail="no_inference_block"
|
||||
)
|
||||
|
||||
|
||||
def _evaluate_inference(
|
||||
payload: dict[str, Any], evidence: list[dict[str, Any]]
|
||||
) -> _InferenceReport:
|
||||
"""Decide the bounded-inference leg with the real entailment engine.
|
||||
|
||||
Premises must be cited evidence references that resolved against the sealed
|
||||
corpus; a rule record contributes its committed formula, a fact record its
|
||||
atom. The query is the claim's atom. ``inferred`` is therefore an actual
|
||||
sound-and-complete entailment decision — citing records that merely *exist*
|
||||
proves nothing. The engine verdict is cross-checked against the
|
||||
independent truth-table oracle; the caller treats disagreement as a
|
||||
defensive refusal.
|
||||
"""
|
||||
inference = payload.get("inference")
|
||||
if not isinstance(inference, dict):
|
||||
return None
|
||||
premise_ids = inference.get("premise_ids") or []
|
||||
known_ids = {record["evidence_id"] for record in payload.get("evidence", [])}
|
||||
if not premise_ids or any(pid not in known_ids for pid in premise_ids):
|
||||
return None
|
||||
return sorted(premise_ids)
|
||||
return _INFERENCE_NOT_PRESENT
|
||||
premise_ids = tuple(inference.get("premise_ids") or ())
|
||||
if not premise_ids:
|
||||
return _InferenceReport(consulted=False, detail="no_premises")
|
||||
|
||||
resolved_by_id = {record["evidence_id"]: record for record in evidence}
|
||||
premises: list[str] = []
|
||||
for premise_id in premise_ids:
|
||||
record = resolved_by_id.get(premise_id)
|
||||
if record is None:
|
||||
return _InferenceReport(consulted=False, detail="premise_unresolved")
|
||||
premises.append(_premise_formula(record))
|
||||
|
||||
query = _claim_atom(payload["claim"])
|
||||
trace = evaluate_entailment_with_trace(tuple(premises), query)
|
||||
oracle_verdict = oracle_entailment(tuple(premises), query)
|
||||
return _InferenceReport(
|
||||
consulted=True,
|
||||
detail="evaluated",
|
||||
premise_ids=tuple(sorted(premise_ids)),
|
||||
outcome=trace.outcome.value,
|
||||
reason=trace.reason,
|
||||
oracle_verdict=oracle_verdict,
|
||||
agreement=trace.outcome.value == oracle_verdict,
|
||||
entailment=trace.as_dict(),
|
||||
)
|
||||
|
||||
|
||||
def _base_trace_summary(payload: dict[str, Any], evidence: list[dict[str, Any]], independent: list[dict[str, Any]]) -> dict[str, Any]:
|
||||
def _base_trace_summary(
|
||||
payload: dict[str, Any],
|
||||
evidence: list[dict[str, Any]],
|
||||
independent: list[dict[str, Any]],
|
||||
inference: _InferenceReport,
|
||||
) -> dict[str, Any]:
|
||||
return {
|
||||
"authority_evaluated": True,
|
||||
"envelope_version": "local-v1",
|
||||
"claim_fingerprint": _claim_fingerprint(payload),
|
||||
"corpus_id": corpus_identifier(),
|
||||
"corpus_sha256": corpus_file_sha256(),
|
||||
"evidence_considered": len(evidence),
|
||||
"independent_support_count": len(independent),
|
||||
"proposer_trace_hash_ignored": "trace_hash" in payload["proposer"],
|
||||
"proposer_state_ignored": "proposed_state" in payload["proposer"],
|
||||
"inference": inference.to_trace_dict(),
|
||||
}
|
||||
|
||||
|
||||
def _authority_path(inference: _InferenceReport) -> list[str]:
|
||||
"""Consulted authorities in order — the entailment engine and the oracle
|
||||
appear only when the inference leg actually ran."""
|
||||
path = [_ROOT_AUTHORITY, _ASSIGN_AUTHORITY, _ENVELOPE_AUTHORITY, _CORPUS_AUTHORITY]
|
||||
if inference.consulted:
|
||||
path.extend([_ENTAIL_AUTHORITY, _ORACLE_AUTHORITY])
|
||||
path.append(_TAXONOMY_AUTHORITY)
|
||||
return path
|
||||
|
||||
|
||||
def _assigned(
|
||||
payload: dict[str, Any],
|
||||
*,
|
||||
|
|
@ -290,6 +498,7 @@ def _assigned(
|
|||
decision_reason: str,
|
||||
evidence_ledger: list[str],
|
||||
trace_summary: dict[str, Any],
|
||||
inference: _InferenceReport,
|
||||
extra: dict[str, Any] | None = None,
|
||||
) -> dict[str, Any]:
|
||||
response = {
|
||||
|
|
@ -297,12 +506,7 @@ def _assigned(
|
|||
"status": "assigned",
|
||||
"request_id": payload["request_id"],
|
||||
"scenario_id": payload["scenario_id"],
|
||||
"authority_path": [
|
||||
_ROOT_AUTHORITY,
|
||||
_ASSIGN_AUTHORITY,
|
||||
_ENVELOPE_AUTHORITY,
|
||||
_TAXONOMY_AUTHORITY,
|
||||
],
|
||||
"authority_path": _authority_path(inference),
|
||||
"decision_reason": decision_reason,
|
||||
"assigned_state": coerce_epistemic_state(state).value,
|
||||
"normative_clearance": coerce_normative_clearance(clearance).value,
|
||||
|
|
@ -318,15 +522,14 @@ def assign_epistemic_state(payload: dict[str, Any]) -> dict[str, Any]:
|
|||
"""CORE's sole authority over the typed epistemic state.
|
||||
|
||||
The proposer's ``proposed_state`` is never read here. The state is derived
|
||||
only from the claim, the evidence bundle, and the bounded-inference block.
|
||||
only from the claim, sealed evidence references, and the bounded-inference
|
||||
block.
|
||||
"""
|
||||
claim = payload["claim"]
|
||||
evidence: list[dict[str, Any]] = payload.get("evidence", [])
|
||||
matching = _matching_evidence(claim, evidence)
|
||||
independent = [record for record in matching if bool(record.get("independent"))]
|
||||
trace_summary = _base_trace_summary(payload, evidence, independent)
|
||||
evidence_refs: list[dict[str, Any]] = payload.get("evidence", [])
|
||||
|
||||
# Scope: refuse claims declared outside the local epistemic envelope.
|
||||
# Scope: refuse claims declared outside the local epistemic envelope before
|
||||
# consulting the corpus at all.
|
||||
if claim["domain"] not in ENVELOPE_DOMAINS:
|
||||
return _finalize(
|
||||
{
|
||||
|
|
@ -345,11 +548,64 @@ def assign_epistemic_state(payload: dict[str, Any]) -> dict[str, Any]:
|
|||
NormativeClearance.UNASSESSABLE
|
||||
).value,
|
||||
"evidence_ledger": [],
|
||||
"trace_summary": trace_summary,
|
||||
"trace_summary": {
|
||||
"authority_evaluated": True,
|
||||
"envelope_version": "local-v1",
|
||||
"claim_fingerprint": _claim_fingerprint(payload),
|
||||
"evidence_considered": len(evidence_refs),
|
||||
"evidence_resolution": "not_consulted",
|
||||
"proposer_trace_hash_ignored": "trace_hash" in payload["proposer"],
|
||||
"proposer_state_ignored": "proposed_state" in payload["proposer"],
|
||||
},
|
||||
"refusal_reason": "outside_epistemic_envelope",
|
||||
}
|
||||
)
|
||||
|
||||
evidence, ref_errors = resolve_evidence_refs(evidence_refs)
|
||||
if ref_errors:
|
||||
return _invalid_evidence_response(payload, ref_errors)
|
||||
matching = _matching_evidence(claim, evidence)
|
||||
independent = _independent_evidence(matching)
|
||||
inference = _evaluate_inference(payload, evidence)
|
||||
trace_summary = _base_trace_summary(payload, evidence, independent, inference)
|
||||
|
||||
# Defensive fail-closed: the engine and the independent oracle must agree
|
||||
# before any inference-derived state is assigned. This path should never
|
||||
# fire (both procedures are sound and complete over the regime); if it
|
||||
# does, refusing is the only honest output.
|
||||
if inference.consulted and inference.agreement is False:
|
||||
return _finalize(
|
||||
{
|
||||
"tool": TOOL_NAME,
|
||||
"status": "refused",
|
||||
"request_id": payload["request_id"],
|
||||
"scenario_id": payload["scenario_id"],
|
||||
"authority_path": _authority_path(inference),
|
||||
"decision_reason": "entailment_oracle_disagreement",
|
||||
"assigned_state": None,
|
||||
"normative_clearance": coerce_normative_clearance(
|
||||
NormativeClearance.UNASSESSABLE
|
||||
).value,
|
||||
"evidence_ledger": [],
|
||||
"trace_summary": trace_summary,
|
||||
"refusal_reason": "entailment_oracle_disagreement",
|
||||
}
|
||||
)
|
||||
|
||||
# Contradicted: the resolved premises propositionally refute the claim.
|
||||
# Conflict is surfaced, never averaged away.
|
||||
if inference.consulted and inference.outcome == Entailment.REFUTED.value:
|
||||
return _assigned(
|
||||
payload,
|
||||
state=EpistemicState.CONTRADICTED,
|
||||
clearance=NormativeClearance.UNASSESSABLE,
|
||||
decision_reason="claim_refuted_by_entailment",
|
||||
evidence_ledger=list(inference.premise_ids),
|
||||
trace_summary=trace_summary,
|
||||
inference=inference,
|
||||
extra={"inference_basis": list(inference.premise_ids)},
|
||||
)
|
||||
|
||||
# Verified: two or more independent records that match subject and predicate.
|
||||
# Clearance stays UNASSESSABLE even here: this demo assigns epistemic
|
||||
# truth-state only and runs no normative/safety/ethics clearance pass, so it
|
||||
|
|
@ -362,19 +618,28 @@ def assign_epistemic_state(payload: dict[str, Any]) -> dict[str, Any]:
|
|||
decision_reason="verified_by_matching_evidence",
|
||||
evidence_ledger=sorted(record["evidence_id"] for record in independent),
|
||||
trace_summary=trace_summary,
|
||||
inference=inference,
|
||||
)
|
||||
|
||||
# Inferred: claim follows from bounded premises and is not directly matched.
|
||||
inference_basis = _resolved_inference_basis(payload)
|
||||
if inference_basis is not None and not matching:
|
||||
# Inferred: the claim is not directly supported but its atom is PROVED from
|
||||
# the resolved premises by the sound-and-complete entailment decision, with
|
||||
# the independent oracle agreeing. Premises that merely resolve do not
|
||||
# infer anything.
|
||||
if (
|
||||
inference.consulted
|
||||
and inference.outcome == Entailment.ENTAILED.value
|
||||
and inference.agreement is True
|
||||
and not matching
|
||||
):
|
||||
return _assigned(
|
||||
payload,
|
||||
state=EpistemicState.INFERRED,
|
||||
clearance=NormativeClearance.UNASSESSABLE,
|
||||
decision_reason="bounded_inference_from_evidence",
|
||||
evidence_ledger=inference_basis,
|
||||
decision_reason="entailed_from_resolved_premises",
|
||||
evidence_ledger=list(inference.premise_ids),
|
||||
trace_summary=trace_summary,
|
||||
extra={"inference_basis": inference_basis},
|
||||
inference=inference,
|
||||
extra={"inference_basis": list(inference.premise_ids)},
|
||||
)
|
||||
|
||||
# Evidenced: at least one supporting record, but not enough to verify.
|
||||
|
|
@ -386,9 +651,11 @@ def assign_epistemic_state(payload: dict[str, Any]) -> dict[str, Any]:
|
|||
decision_reason="evidence_present_but_not_verifying",
|
||||
evidence_ledger=sorted(record["evidence_id"] for record in matching),
|
||||
trace_summary=trace_summary,
|
||||
inference=inference,
|
||||
)
|
||||
|
||||
# Undetermined: nothing grounds the claim. CORE asks rather than guesses.
|
||||
# Undetermined: nothing grounds the claim. CORE asks rather than guesses —
|
||||
# unrelated premises and unsupported claims land here, never in `inferred`.
|
||||
return _assigned(
|
||||
payload,
|
||||
state=EpistemicState.UNDETERMINED,
|
||||
|
|
@ -396,6 +663,7 @@ def assign_epistemic_state(payload: dict[str, Any]) -> dict[str, Any]:
|
|||
decision_reason="insufficient_evidence",
|
||||
evidence_ledger=[],
|
||||
trace_summary=trace_summary,
|
||||
inference=inference,
|
||||
extra={
|
||||
"question": (
|
||||
"CORE has insufficient grounded evidence to assign a determined "
|
||||
|
|
@ -416,10 +684,13 @@ def run_authority(payload: Any) -> dict[str, Any]:
|
|||
|
||||
__all__ = [
|
||||
"ENVELOPE_DOMAINS",
|
||||
"EVIDENCE_CORPUS_PATH",
|
||||
"SCHEMA_PATH",
|
||||
"TOOL_NAME",
|
||||
"assign_epistemic_state",
|
||||
"load_evidence_corpus",
|
||||
"load_schema",
|
||||
"resolve_evidence_refs",
|
||||
"run_authority",
|
||||
"validate_payload",
|
||||
]
|
||||
|
|
|
|||
68
demos/epistemic_truth_state/evidence_corpus.json
Normal file
68
demos/epistemic_truth_state/evidence_corpus.json
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
{
|
||||
"corpus_id": "demo.epistemic_truth_state.evidence_corpus.v1",
|
||||
"records": [
|
||||
{
|
||||
"evidence_id": "ev-a1-trace",
|
||||
"subject": "reviewed_teaching_loop",
|
||||
"predicate": "ran_on_pinned_cognition_pack",
|
||||
"source_kind": "vault",
|
||||
"provenance_root": "vault:pinned-cognition-trace",
|
||||
"assertion": "The vault trace records that the reviewed teaching loop ran on the pinned cognition pack."
|
||||
},
|
||||
{
|
||||
"evidence_id": "ev-a1-replay",
|
||||
"subject": "reviewed_teaching_loop",
|
||||
"predicate": "ran_on_pinned_cognition_pack",
|
||||
"source_kind": "teaching",
|
||||
"provenance_root": "teaching:pinned-cognition-replay",
|
||||
"assertion": "The teaching replay report records that the reviewed teaching loop ran on the pinned cognition pack."
|
||||
},
|
||||
{
|
||||
"evidence_id": "ev-b1-log",
|
||||
"subject": "smoke_suite",
|
||||
"predicate": "passed_on_current_branch",
|
||||
"source_kind": "observation",
|
||||
"provenance_root": "observation:smoke-log",
|
||||
"assertion": "The local smoke log records that the smoke suite passed on the current branch."
|
||||
},
|
||||
{
|
||||
"evidence_id": "ev-c1-tag-on-main",
|
||||
"subject": "release_tag",
|
||||
"predicate": "points_at_main",
|
||||
"source_kind": "premise",
|
||||
"provenance_root": "premise:release-tag",
|
||||
"assertion": "The release tag points at main."
|
||||
},
|
||||
{
|
||||
"evidence_id": "ev-c1-branch-from-main",
|
||||
"subject": "current_branch",
|
||||
"predicate": "branched_from_main",
|
||||
"source_kind": "premise",
|
||||
"provenance_root": "premise:current-branch",
|
||||
"assertion": "The current branch was created from main."
|
||||
},
|
||||
{
|
||||
"evidence_id": "ev-c1-rule-reachability",
|
||||
"source_kind": "premise",
|
||||
"provenance_root": "premise:reachability-rule",
|
||||
"formula": "release_tag__points_at_main & current_branch__branched_from_main -> release_tag__reachable_from_current_branch",
|
||||
"assertion": "Ratified rule: a release tag that points at main is reachable from any branch created from main."
|
||||
},
|
||||
{
|
||||
"evidence_id": "ev-d1-unrelated",
|
||||
"subject": "documentation_pass",
|
||||
"predicate": "merged_to_main",
|
||||
"source_kind": "observation",
|
||||
"provenance_root": "observation:documentation-pass",
|
||||
"assertion": "The documentation pass merged to main."
|
||||
},
|
||||
{
|
||||
"evidence_id": "ev-e1-rumor",
|
||||
"subject": "named_public_stock",
|
||||
"predicate": "closes_higher_tomorrow",
|
||||
"source_kind": "observation",
|
||||
"provenance_root": "observation:market-rumor",
|
||||
"assertion": "A rumor-style observation claims that the named public stock will close higher tomorrow."
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -4,6 +4,7 @@
|
|||
"demos.epistemic_truth_state.authority.validate_payload",
|
||||
"demos.epistemic_truth_state.authority.assign_epistemic_state",
|
||||
"demo_epistemic_truth_state_envelope(local-v1)",
|
||||
"demos.epistemic_truth_state.authority.resolve_evidence_refs",
|
||||
"core.epistemic_state.coerce_epistemic_state"
|
||||
],
|
||||
"decision_reason": "evidence_present_but_not_verifying",
|
||||
|
|
@ -15,13 +16,19 @@
|
|||
"scenario_id": "evidenced-but-not-verified-claim",
|
||||
"status": "assigned",
|
||||
"tool": "core.epistemic_truth_state.review",
|
||||
"trace_hash": "f9f2e153e66aaba9dcb1d7e57bb30947cb7f4dd9b09de3625b12c21b55d80b3c",
|
||||
"trace_hash": "c4fcd4ae033cad4f609ef2e1bcc4a3c1d36647feb4e1931301ce48110cf20c6c",
|
||||
"trace_summary": {
|
||||
"authority_evaluated": true,
|
||||
"claim_fingerprint": "289e494aa06b8bd26b9cd26d61e08b966f78dcfc0f211db250ccf0ec7539a744",
|
||||
"corpus_id": "demo.epistemic_truth_state.evidence_corpus.v1",
|
||||
"corpus_sha256": "62e03b4ac981eaeebdeed64bb2ff9ab1bcfef8cb521ec4029acdbe3b9f120b2e",
|
||||
"envelope_version": "local-v1",
|
||||
"evidence_considered": 1,
|
||||
"independent_support_count": 1,
|
||||
"inference": {
|
||||
"consulted": false,
|
||||
"detail": "no_inference_block"
|
||||
},
|
||||
"proposer_state_ignored": true,
|
||||
"proposer_trace_hash_ignored": true
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,15 +4,20 @@
|
|||
"demos.epistemic_truth_state.authority.validate_payload",
|
||||
"demos.epistemic_truth_state.authority.assign_epistemic_state",
|
||||
"demo_epistemic_truth_state_envelope(local-v1)",
|
||||
"demos.epistemic_truth_state.authority.resolve_evidence_refs",
|
||||
"generate.proof_chain.entail.evaluate_entailment_with_trace",
|
||||
"evals.deductive_logic.oracle.oracle_entailment",
|
||||
"core.epistemic_state.coerce_epistemic_state"
|
||||
],
|
||||
"decision_reason": "bounded_inference_from_evidence",
|
||||
"decision_reason": "entailed_from_resolved_premises",
|
||||
"evidence_ledger": [
|
||||
"ev-c1-branch-from-main",
|
||||
"ev-c1-rule-reachability",
|
||||
"ev-c1-tag-on-main"
|
||||
],
|
||||
"inference_basis": [
|
||||
"ev-c1-branch-from-main",
|
||||
"ev-c1-rule-reachability",
|
||||
"ev-c1-tag-on-main"
|
||||
],
|
||||
"normative_clearance": "unassessable",
|
||||
|
|
@ -20,13 +25,41 @@
|
|||
"scenario_id": "inferred-from-bounded-evidence",
|
||||
"status": "assigned",
|
||||
"tool": "core.epistemic_truth_state.review",
|
||||
"trace_hash": "bc11e858ece140813c2307aa9c6c602650a4cec63972f520f29ba6863f437949",
|
||||
"trace_hash": "3d7e92fceeba328186721e9e4dd33338eff50a72f547988f88f27cbc9cc2526a",
|
||||
"trace_summary": {
|
||||
"authority_evaluated": true,
|
||||
"claim_fingerprint": "12e38c11f88615b1afb8e035e6e942eedd434ea0c6e3b4b25fbb7ff06695204a",
|
||||
"corpus_id": "demo.epistemic_truth_state.evidence_corpus.v1",
|
||||
"corpus_sha256": "62e03b4ac981eaeebdeed64bb2ff9ab1bcfef8cb521ec4029acdbe3b9f120b2e",
|
||||
"envelope_version": "local-v1",
|
||||
"evidence_considered": 2,
|
||||
"evidence_considered": 3,
|
||||
"independent_support_count": 0,
|
||||
"inference": {
|
||||
"consulted": true,
|
||||
"detail": "evaluated",
|
||||
"engine_oracle_agreement": true,
|
||||
"entailment_trace": {
|
||||
"conjunction_key": "0:release_tag__reachable_from_current_branch?T:F;1:release_tag__points_at_main?@0:F;2:current_branch__branched_from_main?@1:F",
|
||||
"entailment_check_key": "T",
|
||||
"outcome": "entailed",
|
||||
"premise_keys": [
|
||||
"0:release_tag__points_at_main?T:F",
|
||||
"0:current_branch__branched_from_main?T:F",
|
||||
"0:release_tag__reachable_from_current_branch?T:F;1:release_tag__points_at_main?@0:T;2:current_branch__branched_from_main?@1:T"
|
||||
],
|
||||
"query_key": "0:release_tag__reachable_from_current_branch?T:F",
|
||||
"reason": "tautological_implication",
|
||||
"refutation_check_key": "0:release_tag__reachable_from_current_branch?F:T;1:release_tag__points_at_main?@0:T;2:current_branch__branched_from_main?@1:T"
|
||||
},
|
||||
"oracle_verdict": "entailed",
|
||||
"outcome": "entailed",
|
||||
"premise_ids": [
|
||||
"ev-c1-branch-from-main",
|
||||
"ev-c1-rule-reachability",
|
||||
"ev-c1-tag-on-main"
|
||||
],
|
||||
"reason": "tautological_implication"
|
||||
},
|
||||
"proposer_state_ignored": true,
|
||||
"proposer_trace_hash_ignored": true
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,13 +13,13 @@
|
|||
"scenario_id": "refused-outside-scope",
|
||||
"status": "refused",
|
||||
"tool": "core.epistemic_truth_state.review",
|
||||
"trace_hash": "c9ef9560bcf71052f9e4f323d5f6c49dc23113dcaa6a63048cfdffafec6dd024",
|
||||
"trace_hash": "f1d8936f7616d2739041edd1b7e2c85b4355e39665d94c21b9a4d2e6e0c802f8",
|
||||
"trace_summary": {
|
||||
"authority_evaluated": true,
|
||||
"claim_fingerprint": "ef9317e405906823799755113ccb216ab39dd7b055c9f9883ada6480b80ef98c",
|
||||
"envelope_version": "local-v1",
|
||||
"evidence_considered": 1,
|
||||
"independent_support_count": 1,
|
||||
"evidence_resolution": "not_consulted",
|
||||
"proposer_state_ignored": true,
|
||||
"proposer_trace_hash_ignored": true
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
"demos.epistemic_truth_state.authority.validate_payload",
|
||||
"demos.epistemic_truth_state.authority.assign_epistemic_state",
|
||||
"demo_epistemic_truth_state_envelope(local-v1)",
|
||||
"demos.epistemic_truth_state.authority.resolve_evidence_refs",
|
||||
"core.epistemic_state.coerce_epistemic_state"
|
||||
],
|
||||
"decision_reason": "insufficient_evidence",
|
||||
|
|
@ -14,13 +15,19 @@
|
|||
"scenario_id": "undetermined-insufficient-evidence",
|
||||
"status": "assigned",
|
||||
"tool": "core.epistemic_truth_state.review",
|
||||
"trace_hash": "35b319eb0186be2d9bedf65263d5acb8f397f747e7efe1ea01960655deafc7d2",
|
||||
"trace_hash": "80559d4b02668e36d7858097c09eac3e6e4e10c20615fdc2c9b5f3c4afa09cdf",
|
||||
"trace_summary": {
|
||||
"authority_evaluated": true,
|
||||
"claim_fingerprint": "dc8720472531486a19edbb82c2accd279d291afe2a797c23d2745469c4f91662",
|
||||
"corpus_id": "demo.epistemic_truth_state.evidence_corpus.v1",
|
||||
"corpus_sha256": "62e03b4ac981eaeebdeed64bb2ff9ab1bcfef8cb521ec4029acdbe3b9f120b2e",
|
||||
"envelope_version": "local-v1",
|
||||
"evidence_considered": 1,
|
||||
"independent_support_count": 0,
|
||||
"inference": {
|
||||
"consulted": false,
|
||||
"detail": "no_inference_block"
|
||||
},
|
||||
"proposer_state_ignored": true,
|
||||
"proposer_trace_hash_ignored": true
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,54 @@
|
|||
{
|
||||
"assigned_state": "undetermined",
|
||||
"authority_path": [
|
||||
"demos.epistemic_truth_state.authority.validate_payload",
|
||||
"demos.epistemic_truth_state.authority.assign_epistemic_state",
|
||||
"demo_epistemic_truth_state_envelope(local-v1)",
|
||||
"demos.epistemic_truth_state.authority.resolve_evidence_refs",
|
||||
"generate.proof_chain.entail.evaluate_entailment_with_trace",
|
||||
"evals.deductive_logic.oracle.oracle_entailment",
|
||||
"core.epistemic_state.coerce_epistemic_state"
|
||||
],
|
||||
"decision_reason": "insufficient_evidence",
|
||||
"evidence_ledger": [],
|
||||
"normative_clearance": "unassessable",
|
||||
"question": "CORE has insufficient grounded evidence to assign a determined epistemic state to this claim. Provide supporting, refuting, or premise evidence.",
|
||||
"request_id": "demo-eps-g1",
|
||||
"scenario_id": "unrelated-premise-still-undetermined",
|
||||
"status": "assigned",
|
||||
"tool": "core.epistemic_truth_state.review",
|
||||
"trace_hash": "48c9932a5dd99f1a41ee879f1f39f6de5e365162797129c23f339054a5e92d1b",
|
||||
"trace_summary": {
|
||||
"authority_evaluated": true,
|
||||
"claim_fingerprint": "9f381a36a05cb5c0f98ce7339522abb36be89f142f7668aae4359e8a0367537b",
|
||||
"corpus_id": "demo.epistemic_truth_state.evidence_corpus.v1",
|
||||
"corpus_sha256": "62e03b4ac981eaeebdeed64bb2ff9ab1bcfef8cb521ec4029acdbe3b9f120b2e",
|
||||
"envelope_version": "local-v1",
|
||||
"evidence_considered": 1,
|
||||
"independent_support_count": 0,
|
||||
"inference": {
|
||||
"consulted": true,
|
||||
"detail": "evaluated",
|
||||
"engine_oracle_agreement": true,
|
||||
"entailment_trace": {
|
||||
"conjunction_key": "0:documentation_pass__merged_to_main?T:F",
|
||||
"entailment_check_key": "0:vault_recall__is_approximate?T:F;1:documentation_pass__merged_to_main?@0:T",
|
||||
"outcome": "unknown",
|
||||
"premise_keys": [
|
||||
"0:documentation_pass__merged_to_main?T:F"
|
||||
],
|
||||
"query_key": "0:vault_recall__is_approximate?T:F",
|
||||
"reason": "undetermined",
|
||||
"refutation_check_key": "0:vault_recall__is_approximate?F:T;1:documentation_pass__merged_to_main?@0:T"
|
||||
},
|
||||
"oracle_verdict": "unknown",
|
||||
"outcome": "unknown",
|
||||
"premise_ids": [
|
||||
"ev-d1-unrelated"
|
||||
],
|
||||
"reason": "undetermined"
|
||||
},
|
||||
"proposer_state_ignored": true,
|
||||
"proposer_trace_hash_ignored": true
|
||||
}
|
||||
}
|
||||
|
|
@ -4,6 +4,7 @@
|
|||
"demos.epistemic_truth_state.authority.validate_payload",
|
||||
"demos.epistemic_truth_state.authority.assign_epistemic_state",
|
||||
"demo_epistemic_truth_state_envelope(local-v1)",
|
||||
"demos.epistemic_truth_state.authority.resolve_evidence_refs",
|
||||
"core.epistemic_state.coerce_epistemic_state"
|
||||
],
|
||||
"decision_reason": "verified_by_matching_evidence",
|
||||
|
|
@ -16,13 +17,19 @@
|
|||
"scenario_id": "verified-supported-claim",
|
||||
"status": "assigned",
|
||||
"tool": "core.epistemic_truth_state.review",
|
||||
"trace_hash": "1341c27c5906ae528ecc1f0cc4ebd3f71db68f138f6d8365fe0e93dd2d7f7097",
|
||||
"trace_hash": "fd0042f5f2bea77d15bfe387faa2a1045e38c61593d93232e35653f492890154",
|
||||
"trace_summary": {
|
||||
"authority_evaluated": true,
|
||||
"claim_fingerprint": "cef9198360d02ce3133c1095e776ae86a714fd1c9718aa3576616f935eccdf98",
|
||||
"corpus_id": "demo.epistemic_truth_state.evidence_corpus.v1",
|
||||
"corpus_sha256": "62e03b4ac981eaeebdeed64bb2ff9ab1bcfef8cb521ec4029acdbe3b9f120b2e",
|
||||
"envelope_version": "local-v1",
|
||||
"evidence_considered": 2,
|
||||
"independent_support_count": 2,
|
||||
"inference": {
|
||||
"consulted": false,
|
||||
"detail": "no_inference_block"
|
||||
},
|
||||
"proposer_state_ignored": true,
|
||||
"proposer_trace_hash_ignored": true
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,11 +20,7 @@
|
|||
"evidence": [
|
||||
{
|
||||
"evidence_id": "ev-b1-log",
|
||||
"subject": "smoke_suite",
|
||||
"predicate": "passed_on_current_branch",
|
||||
"supports": true,
|
||||
"independent": true,
|
||||
"source_kind": "observation"
|
||||
"content_sha256": "22049f3356d6e5398f80ad58683ba94ee559296b85ee009b02cf04dd453aa773"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,24 +20,24 @@
|
|||
"evidence": [
|
||||
{
|
||||
"evidence_id": "ev-c1-tag-on-main",
|
||||
"subject": "release_tag",
|
||||
"predicate": "points_at_main",
|
||||
"supports": true,
|
||||
"independent": true,
|
||||
"source_kind": "premise"
|
||||
"content_sha256": "83dbbf3ff366458233ed71e153d3608a643ea6d6646958148c8746c181e00be2"
|
||||
},
|
||||
{
|
||||
"evidence_id": "ev-c1-branch-from-main",
|
||||
"subject": "current_branch",
|
||||
"predicate": "branched_from_main",
|
||||
"supports": true,
|
||||
"independent": true,
|
||||
"source_kind": "premise"
|
||||
"content_sha256": "bb792e8ff12a6a29f5dc50e988aa9012ae68a010cbe42096c7727266ee1b9444"
|
||||
},
|
||||
{
|
||||
"evidence_id": "ev-c1-rule-reachability",
|
||||
"content_sha256": "b9a51ca7d9d596b1ac91a85b11420c92c1bbdb989a7739621200a3590e591573"
|
||||
}
|
||||
],
|
||||
"inference": {
|
||||
"mode": "bounded_deductive",
|
||||
"premise_ids": ["ev-c1-tag-on-main", "ev-c1-branch-from-main"]
|
||||
"premise_ids": [
|
||||
"ev-c1-tag-on-main",
|
||||
"ev-c1-branch-from-main",
|
||||
"ev-c1-rule-reachability"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,11 +20,7 @@
|
|||
"evidence": [
|
||||
{
|
||||
"evidence_id": "ev-e1-rumor",
|
||||
"subject": "named_public_stock",
|
||||
"predicate": "closes_higher_tomorrow",
|
||||
"supports": true,
|
||||
"independent": true,
|
||||
"source_kind": "observation"
|
||||
"content_sha256": "5c41a3b6b0e1ca53e688c470be67740b628f689b304247cb72ce7fc382d56e1a"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,11 +20,7 @@
|
|||
"evidence": [
|
||||
{
|
||||
"evidence_id": "ev-d1-unrelated",
|
||||
"subject": "documentation_pass",
|
||||
"predicate": "merged_to_main",
|
||||
"supports": true,
|
||||
"independent": true,
|
||||
"source_kind": "observation"
|
||||
"content_sha256": "d47df7dc3a7d7e51dcac951de2981777f612af4c40924b7f8d9e8abca3b98af2"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,31 @@
|
|||
{
|
||||
"tool": "core.epistemic_truth_state.review",
|
||||
"expected_status": "assigned",
|
||||
"arguments": {
|
||||
"request_id": "demo-eps-g1",
|
||||
"scenario_id": "unrelated-premise-still-undetermined",
|
||||
"proposer": {
|
||||
"lane": "frontier_fixture",
|
||||
"model_family": "model_style_proposer",
|
||||
"proposal_id": "proposal-g1",
|
||||
"proposed_state": "inferred",
|
||||
"trace_hash": "9999999999999999999999999999999999999999999999999999999999999999"
|
||||
},
|
||||
"claim": {
|
||||
"text": "Vault recall is approximate.",
|
||||
"domain": "demo.local_factual",
|
||||
"subject": "vault_recall",
|
||||
"predicate": "is_approximate"
|
||||
},
|
||||
"evidence": [
|
||||
{
|
||||
"evidence_id": "ev-d1-unrelated",
|
||||
"content_sha256": "d47df7dc3a7d7e51dcac951de2981777f612af4c40924b7f8d9e8abca3b98af2"
|
||||
}
|
||||
],
|
||||
"inference": {
|
||||
"mode": "bounded_deductive",
|
||||
"premise_ids": ["ev-d1-unrelated"]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -20,19 +20,11 @@
|
|||
"evidence": [
|
||||
{
|
||||
"evidence_id": "ev-a1-trace",
|
||||
"subject": "reviewed_teaching_loop",
|
||||
"predicate": "ran_on_pinned_cognition_pack",
|
||||
"supports": true,
|
||||
"independent": true,
|
||||
"source_kind": "vault"
|
||||
"content_sha256": "a507b19de0860fafdfc00e7d581a4c1b5ded7f1510e052ba92f7325abfebbaf5"
|
||||
},
|
||||
{
|
||||
"evidence_id": "ev-a1-replay",
|
||||
"subject": "reviewed_teaching_loop",
|
||||
"predicate": "ran_on_pinned_cognition_pack",
|
||||
"supports": true,
|
||||
"independent": true,
|
||||
"source_kind": "teaching"
|
||||
"content_sha256": "a8564c2daa27c7fe851711f068b682ffa87f769014a13a7d5b5625e44ebb9679"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "core.epistemic_truth_state.review",
|
||||
"title": "CORE epistemic truth-state authority demo",
|
||||
"description": "Submit one model-style claim proposal to CORE's local deterministic epistemic-state authority. CORE validates a closed payload, ignores any proposer-supplied proposed_state and trace hash, assigns a typed epistemic state drawn from the canonical core.epistemic_state taxonomy, derives normative clearance, builds an evidence ledger, and returns assigned | refused | invalid plus a deterministic trace artifact. The proposer cannot set the assigned state, status, clearance, evidence ledger, authority path, or trace hash.",
|
||||
"description": "Submit one model-style claim proposal to CORE's local deterministic epistemic-state authority. CORE validates a closed payload, resolves sealed evidence references by content hash, ignores any proposer-supplied proposed_state and trace hash, decides the bounded-inference leg with the sound-and-complete ROBDD entailment engine cross-checked against an independent truth-table oracle, assigns a typed epistemic state drawn from the canonical core.epistemic_state taxonomy, derives normative clearance, builds an evidence ledger, and returns assigned | refused | invalid plus a deterministic trace artifact. The proposer cannot set the assigned state, status, clearance, evidence ledger, authority path, trace hash, support labels, or independence labels — and cannot mint inferred by citing records that merely exist, because inferred requires an actual entailment proof.",
|
||||
"inputSchema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
|
@ -56,12 +56,14 @@
|
|||
"subject": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"maxLength": 120
|
||||
"maxLength": 120,
|
||||
"pattern": "^[a-z][a-z0-9_]*$"
|
||||
},
|
||||
"predicate": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"maxLength": 120
|
||||
"maxLength": 120,
|
||||
"pattern": "^[a-z][a-z0-9_]*$"
|
||||
}
|
||||
},
|
||||
"required": ["text", "domain", "subject", "predicate"],
|
||||
|
|
@ -76,28 +78,12 @@
|
|||
"type": "string",
|
||||
"pattern": "^[A-Za-z0-9._-]{1,64}$"
|
||||
},
|
||||
"subject": {
|
||||
"content_sha256": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"maxLength": 120
|
||||
},
|
||||
"predicate": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"maxLength": 120
|
||||
},
|
||||
"supports": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"independent": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"source_kind": {
|
||||
"type": "string",
|
||||
"enum": ["pack", "teaching", "vault", "observation", "premise"]
|
||||
"pattern": "^[a-f0-9]{64}$"
|
||||
}
|
||||
},
|
||||
"required": ["evidence_id", "subject", "predicate", "supports"],
|
||||
"required": ["evidence_id", "content_sha256"],
|
||||
"additionalProperties": false
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ This checklist applies to public CORE demos.
|
|||
|
||||
- [ ] Demo purpose is stated narrowly.
|
||||
- [ ] Demo status is clear: merged, draft PR, proposed, or not yet implemented.
|
||||
- [ ] Demo evidence class is stated: substrate-capability, interface-contract, simulation-only, or proposed.
|
||||
- [ ] README includes "what this proves."
|
||||
- [ ] README includes "what this does not prove."
|
||||
- [ ] README avoids named-company outreach strategy.
|
||||
|
|
@ -34,10 +35,19 @@ This checklist applies to public CORE demos.
|
|||
|
||||
- [ ] Proposer input cannot set final authority status.
|
||||
- [ ] Proposer input cannot smuggle final action artifacts.
|
||||
- [ ] Proposer input cannot indirectly decide the result through trusted support, independence, verdict, or clearance labels.
|
||||
- [ ] Invalid payloads fail closed.
|
||||
- [ ] Refusal and ask outcomes are first-class successes.
|
||||
- [ ] Authorized outputs, if present, are inert artifacts unless a later production system explicitly implements execution.
|
||||
|
||||
## Evidence strength
|
||||
|
||||
- [ ] Capability claims route through a real CORE operator, runtime path, sealed eval lane, or independently checked proof surface.
|
||||
- [ ] Interface-contract demos are not described as substrate-capability demos.
|
||||
- [ ] Fixture evidence is labeled as fixture evidence.
|
||||
- [ ] Sealed-corpus or independent-oracle claims name the corpus/oracle and the no-shared-code boundary.
|
||||
- [ ] Boolean/string policy demos are framed as boundary checks unless another substrate decision is actually present.
|
||||
|
||||
## Public hygiene
|
||||
|
||||
- [ ] No named-person outreach planning.
|
||||
|
|
|
|||
|
|
@ -22,12 +22,31 @@ Public repository docs must not include:
|
|||
- company-specific red-team personas;
|
||||
- current-facts dossiers for outreach.
|
||||
|
||||
## Evidence strength
|
||||
|
||||
Public demos must distinguish the strength of the evidence they provide.
|
||||
|
||||
**Substrate-capability demos** route the proposal through a real CORE operator,
|
||||
runtime path, sealed eval lane, or independently checked proof surface. These demos
|
||||
may support capability claims, within their stated envelope.
|
||||
|
||||
**Interface-contract demos** prove the typed boundary: closed schema, fail-closed
|
||||
validation, proposer-held status ignored, inert outputs, deterministic traces, and
|
||||
no side effects. These demos are useful, but they must not be described as proving
|
||||
deep CORE reasoning capability by themselves.
|
||||
|
||||
This distinction is load-bearing. A demo that only checks strings, booleans, or
|
||||
schema shape may prove an authority boundary; it does not prove that the geometric
|
||||
or deductive substrate made a non-trivial decision.
|
||||
|
||||
## Demonstrated
|
||||
|
||||
### Hybrid Verification Demo (#687 — authority over claims)
|
||||
|
||||
Status: merged (PR #687).
|
||||
|
||||
Evidence class: substrate-capability demo.
|
||||
|
||||
Purpose: demonstrate a bounded proposer-to-substrate verification path with typed outcomes. A model-style proposer submits a claim; the substrate, not the proposer, decides the typed outcome.
|
||||
|
||||
Hard finding recorded by this demo: agreement between reasoning paths is not reliable safety. Multiple paths can agree and still be wrong. Authority must live at the typed boundary, not merely in multiple model outputs.
|
||||
|
|
@ -51,8 +70,16 @@ Public safety boundary:
|
|||
|
||||
Status: merged (PR #688, merge commit `c55f7dfb`).
|
||||
|
||||
Evidence class: interface-contract demo.
|
||||
|
||||
Purpose: demonstrate that a model-style proposer may submit a typed action proposal, while CORE alone may authorize, ask, refuse, or invalidate. The authorized output is an inert `licensed_action` artifact only; no external side effect executes and the proposer holds no execution authority.
|
||||
|
||||
Evidence caveat: this demo proves the digital-action boundary contract. Its local
|
||||
authority evaluator is deliberately small, so it must not be described as proving
|
||||
general tool-safety reasoning or production MCP capability. Its value is that the
|
||||
proposer cannot self-authorize, inject a license, supply a trusted trace hash, or
|
||||
cause side effects.
|
||||
|
||||
Public outcome vocabulary:
|
||||
|
||||
- `authorized`
|
||||
|
|
@ -69,45 +96,81 @@ Public safety boundary:
|
|||
- inert `licensed_action` artifact only;
|
||||
- MCP-shaped, not production MCP.
|
||||
|
||||
## Proposed
|
||||
### Epistemic Truth-State Demo (#690 — authority over state assignment)
|
||||
|
||||
Recommended order of next public evidence:
|
||||
Status: merged (PR #690); hardened in this reconciliation pass to use sealed
|
||||
evidence references and an entailment-decided inference leg.
|
||||
|
||||
1. Epistemic Truth-State Demo (next target);
|
||||
2. Embodied Authority Simulation Demo (simulation-only);
|
||||
3. SaaS / On-Prem Boundary Demo.
|
||||
Evidence class: local epistemic-state authority demo; the `inferred` leg is a
|
||||
substrate-capability decision (it routes through the proof-chain entailment
|
||||
engine with an independent-oracle cross-check).
|
||||
|
||||
Merged evidence so far establishes two authority boundaries: authority over claims (#687) and authority over proposed tool actions (#688). The next target extends the same pattern to epistemic state.
|
||||
Purpose: show that a model-style proposer can submit a claim, sealed evidence
|
||||
references, and `proposed_state`, while CORE emits the canonical typed state and
|
||||
deterministic trace. The proposer controls neither the assigned state nor the
|
||||
trace.
|
||||
|
||||
### Epistemic Truth-State Demo (next public evidence target)
|
||||
Public outcome vocabulary:
|
||||
|
||||
Status: proposed.
|
||||
|
||||
Purpose: show that a model-style proposer can submit a claim, answer, or state proposal, but CORE assigns the typed epistemic state and emits deterministic, replayable evidence. The proposer controls neither the assigned state nor the trace.
|
||||
|
||||
Possible states (illustrative; the implementing PR fixes the closed set):
|
||||
|
||||
- `perceived`;
|
||||
- `evidenced`;
|
||||
- `verified`;
|
||||
- `decoded`;
|
||||
- `evidenced`;
|
||||
- `inferred`;
|
||||
- `refused`;
|
||||
- `contradicted`;
|
||||
- `undetermined`;
|
||||
- `scope_boundary`;
|
||||
- `invalid`.
|
||||
|
||||
Possible outputs:
|
||||
Evidence caveat: the evidence corpus is still local fixture evidence, not live
|
||||
vault retrieval or arbitrary web evidence. The proposer supplies evidence
|
||||
references only; CORE resolves them by committed content hash and computes support
|
||||
and independence from sealed corpus records. `inferred` is assigned only when the
|
||||
cited premises propositionally entail the claim's atom under the sound-and-complete
|
||||
ROBDD entailment engine, cross-checked against the independent truth-table oracle;
|
||||
citing records that merely exist yields `undetermined` (the committed
|
||||
`unrelated-premise-still-undetermined` scenario exercises that attack). The demo
|
||||
must not be described as production epistemic evaluation across arbitrary evidence
|
||||
sources.
|
||||
|
||||
- state ledger entry;
|
||||
- evidence / provenance spans;
|
||||
- deterministic trace hash;
|
||||
- `ask` or refusal when evidence is insufficient;
|
||||
- no proposer-controlled state;
|
||||
- no proposer-controlled trace;
|
||||
- `invalid` rejected before state evaluation.
|
||||
## Proposed
|
||||
|
||||
No claim is made here that the full demo is implemented until a PR lands.
|
||||
Recommended order of next public evidence:
|
||||
|
||||
1. Deductive Entailment / Proof-Carrying Authority Demo (next substrate-capability target);
|
||||
2. Embodied Authority Simulation Demo (simulation-only);
|
||||
3. SaaS / On-Prem Boundary Demo.
|
||||
|
||||
Merged evidence establishes three authority boundaries: authority over claims
|
||||
(#687), proposed tool actions (#688), and epistemic state assignment (#690). The
|
||||
next public target should make the non-trivial substrate decision visible: a
|
||||
proposer supplies premises, conclusion, and claimed verdict; CORE decides through
|
||||
the existing deductive/proof surface and emits replayable proof evidence.
|
||||
|
||||
### Deductive Entailment / Proof-Carrying Authority Demo
|
||||
|
||||
Status: proposed.
|
||||
|
||||
Purpose: demonstrate a non-trivial authority boundary over formal entailment. The
|
||||
proposer submits premises, a conclusion, and a claimed verdict. CORE decides via
|
||||
the existing proof-chain / deductive-logic substrate, with trace evidence that can
|
||||
be checked against the independent truth-table oracle discipline already used by
|
||||
the deductive lane.
|
||||
|
||||
Required outcomes:
|
||||
|
||||
- `entailed`;
|
||||
- `refuted`;
|
||||
- `unknown`;
|
||||
- `refused`;
|
||||
- `invalid`.
|
||||
|
||||
Required proof obligations:
|
||||
|
||||
- proposer verdict ignored;
|
||||
- malformed or out-of-regime logic refused;
|
||||
- inconsistent premises refused rather than vacuously proving everything;
|
||||
- at least one scenario where the proposer is wrong and CORE's verdict differs;
|
||||
- deterministic trace includes canonical proof keys or certificate evidence;
|
||||
- no shared-code oracle is presented as independent evidence.
|
||||
|
||||
### Embodied Authority Simulation Demo
|
||||
|
||||
|
|
|
|||
|
|
@ -152,9 +152,7 @@ deterministically, with the proof chain as the audit artifact — the logical fo
|
|||
of the *"structural coherence metric"* ADR-0021 names as the successor to curator
|
||||
mediation. What review still gates there is the faithfulness of the reading, not
|
||||
the deduction. This proof-carrying promotion path is **specified but not yet
|
||||
wired** (see
|
||||
[`docs/issues/proof-carrying-coherence-promotion.md`](issues/proof-carrying-coherence-promotion.md));
|
||||
until it lands, all promotion is curator-mediated.
|
||||
wired**; until it lands, all promotion is curator-mediated.
|
||||
|
||||
This is not a safety overlay. It is a consequence of the decoding thesis: if the
|
||||
system decodes a reality that already is, then inputs that contradict — or merely
|
||||
|
|
@ -384,8 +382,13 @@ behavioral testing of a black-box sampler.
|
|||
## Concrete Evidence — Merged Demos (2026-06-11)
|
||||
|
||||
The claims in §4 are abstract without pointers to reproducible artifacts. This
|
||||
section ties each abstract property to a specific merged demo, trace hash, and
|
||||
runnable command. All three demos are in the public repository under `demos/`.
|
||||
section ties those properties to merged demos, trace hashes, and runnable
|
||||
commands. The demos are not all the same kind of evidence. #687 routes through the
|
||||
real derivation and ASK machinery and is the substrate-capability anchor. #688 is
|
||||
an interface-contract demo. #690 is a local epistemic-state authority demo using a
|
||||
sealed fixture corpus. They prove that proposer-held status cannot cross the typed
|
||||
boundary, but they must not be mistaken for production tool safety or arbitrary
|
||||
evidence evaluation.
|
||||
|
||||
### Authority over claims — PR #687, merge `3ba65d51`
|
||||
|
||||
|
|
@ -412,11 +415,11 @@ architecture would not.
|
|||
|
||||
### Authority over proposed tool actions — PR #688, merge `c55f7dfb`
|
||||
|
||||
`demos/claude_tool_authority/` demonstrates the same authority boundary for
|
||||
proposed digital actions across four typed outcomes. A model-style proposer submits
|
||||
action proposals; CORE alone authorizes, asks, refuses, or invalidates. Authorized
|
||||
outputs are inert `licensed_action` artifacts; `execution_performed: false` on every
|
||||
scenario.
|
||||
`demos/claude_tool_authority/` demonstrates the same typed boundary for proposed
|
||||
digital actions across four outcomes. A model-style proposer submits action
|
||||
proposals; the local authority envelope authorizes, asks, refuses, or invalidates.
|
||||
Authorized outputs are inert `licensed_action` artifacts; `execution_performed:
|
||||
false` on every scenario.
|
||||
|
||||
Representative trace hashes:
|
||||
- Authorized (inert): `9e797710ed34dfa5…` (`write_local_note`, `proposer_trace_hash_ignored: true`)
|
||||
|
|
@ -426,19 +429,26 @@ Representative trace hashes:
|
|||
|
||||
Run: `python demos/claude_tool_authority/run_demo.py`
|
||||
|
||||
Evidence caveat: #688 is an interface-contract demo. It proves no proposer can
|
||||
self-authorize, smuggle a license, provide a trusted trace hash, or cause a side
|
||||
effect through this boundary. It does not prove production MCP integration or
|
||||
general autonomous tool-safety reasoning; its decision core is intentionally a
|
||||
small local envelope.
|
||||
|
||||
### Authority over epistemic state assignment — PR #690, merge `e80c8eae`
|
||||
|
||||
`demos/epistemic_truth_state/` demonstrates the same authority boundary for
|
||||
epistemic state assignment across six typed outcomes. A model-style proposer
|
||||
submits a claim with evidence and a `proposed_state`; CORE assigns the canonical
|
||||
state from the evidence. `proposer_state_ignored: true` on every output.
|
||||
`demos/epistemic_truth_state/` demonstrates the same typed boundary for epistemic
|
||||
state assignment across six outcomes. A model-style proposer submits a claim,
|
||||
sealed evidence references, and a `proposed_state`; the demo assigns a canonical
|
||||
state from committed corpus records whose content hashes must match.
|
||||
`proposer_state_ignored: true` on every non-invalid output.
|
||||
|
||||
Typed state vocabulary: `verified`, `evidenced`, `inferred`, `undetermined`,
|
||||
`scope_boundary`. A proposer that injects `assigned_state` or `authority_path` into
|
||||
the request payload is rejected at the typed schema boundary before evaluation.
|
||||
|
||||
Representative trace hashes:
|
||||
- Verified: `1341c27c5906ae52…` (2 independent evidence items, `normative_clearance: unassessable`)
|
||||
- Verified: `1341c27c5906ae52…` (2 sealed corpus records with distinct provenance roots, `normative_clearance: unassessable`)
|
||||
- Evidenced: `f9f2e153e66aaba9…` (1 item, below threshold — proposer proposed `verified`)
|
||||
- Inferred: `bc11e858ece14081…` (premise-only evidence — proposer proposed `verified`)
|
||||
- Undetermined: `35b319eb0186be2d…` (off-topic evidence)
|
||||
|
|
@ -448,11 +458,12 @@ Representative trace hashes:
|
|||
Run: `python demos/epistemic_truth_state/run_demo.py`
|
||||
|
||||
**Honesty note:** `normative_clearance` is `"unassessable"` on every non-invalid
|
||||
scenario; the invalid scenario has `null` (no evaluation reached). The demos do not
|
||||
perform a normative, safety, or ethics clearance pass for any scenario. The
|
||||
`deterministic replay` and `identity protection` claims in §4 are substrate
|
||||
properties; the epistemic state demos extend them to claim/action/state authority
|
||||
surfaces not covered in the original paper.
|
||||
scenario; the invalid scenario has `null` because evaluation never reached the
|
||||
authority path. The demo runs no normative, safety, or ethics clearance pass. The
|
||||
evidence corpus is local fixture evidence, so #690 should be read as a
|
||||
state-authority demo over a sealed local corpus, not as proof that CORE evaluates
|
||||
arbitrary evidence sources. The next proof obligation is proof-carrying entailment
|
||||
evidence for claims that should move from stated premises to promoted knowledge.
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -463,10 +474,10 @@ generation is the right substrate for cognition in the first place.
|
|||
|
||||
CORE is a running argument that it is not. The argument is not in this paper. It
|
||||
is in the versor invariant, the zero-wrong eval gate, the deterministic trace
|
||||
hash, the reviewed teaching path, the two-layer identity firewall, and now in three
|
||||
public demos where a deterministic substrate holds exclusive authority over claims,
|
||||
proposed actions, and epistemic state — each of which would fail visibly if the
|
||||
thesis were wrong.
|
||||
hash, the reviewed teaching path, the two-layer identity firewall, and the public
|
||||
authority-demo stack. The strongest current demo proves substrate authority over
|
||||
claims; the surrounding boundary demos expose the exact places where broader
|
||||
action and epistemic authority still need harder evidence.
|
||||
|
||||
The code is open source under the CORE Non-Commercial License.
|
||||
All commercial licensing inquiries: shayj292@gmail.com
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ SCENARIOS = {
|
|||
"verified-supported-claim": ("assigned", "verified"),
|
||||
"evidenced-but-not-verified-claim": ("assigned", "evidenced"),
|
||||
"inferred-from-bounded-evidence": ("assigned", "inferred"),
|
||||
"unrelated-premise-still-undetermined": ("assigned", "undetermined"),
|
||||
"undetermined-insufficient-evidence": ("assigned", "undetermined"),
|
||||
"refused-outside-scope": ("refused", "scope_boundary"),
|
||||
"invalid-state-smuggling-attempt": ("invalid", None),
|
||||
|
|
@ -110,15 +111,34 @@ def test_verified_requires_matching_evidence():
|
|||
assert downgraded["assigned_state"] == "evidenced"
|
||||
assert downgraded["decision_reason"] == "evidence_present_but_not_verifying"
|
||||
|
||||
# Subject/predicate mismatch is not matching evidence at all.
|
||||
# A corpus reference for a different subject/predicate is not matching
|
||||
# evidence at all.
|
||||
mismatched = _arguments("verified-supported-claim")
|
||||
for record in mismatched["evidence"]:
|
||||
record["predicate"] = "something_else"
|
||||
mismatched["evidence"] = _arguments("undetermined-insufficient-evidence")["evidence"]
|
||||
none_match = authority.run_authority(mismatched)
|
||||
assert none_match["assigned_state"] == "undetermined"
|
||||
assert none_match["decision_reason"] == "insufficient_evidence"
|
||||
|
||||
|
||||
def test_proposer_cannot_supply_support_or_independence_labels():
|
||||
payload = _arguments("verified-supported-claim")
|
||||
payload["evidence"][0]["supports"] = True
|
||||
payload["evidence"][0]["independent"] = True
|
||||
response = authority.run_authority(payload)
|
||||
assert response["status"] == "invalid"
|
||||
assert "payload.evidence[0] unexpected property 'supports'" in response["invalid_reason"]
|
||||
assert "payload.evidence[0] unexpected property 'independent'" in response["invalid_reason"]
|
||||
|
||||
|
||||
def test_evidence_reference_hash_mismatch_is_invalid():
|
||||
payload = _arguments("verified-supported-claim")
|
||||
payload["evidence"][0]["content_sha256"] = "0" * 64
|
||||
response = authority.run_authority(payload)
|
||||
assert response["status"] == "invalid"
|
||||
assert response["decision_reason"] == "invalid_evidence_reference"
|
||||
assert "content hash mismatch for evidence reference 'ev-a1-trace'" in response["invalid_reason"]
|
||||
|
||||
|
||||
def test_clearance_is_unassessable_for_all_non_invalid_outputs():
|
||||
# The demo assigns epistemic truth-state only; it runs no normative/safety/
|
||||
# ethics clearance pass, so it must never positively clear anything.
|
||||
|
|
@ -138,19 +158,96 @@ def test_evidenced_state_for_single_support():
|
|||
assert response["evidence_ledger"] == ["ev-b1-log"]
|
||||
|
||||
|
||||
def test_inferred_includes_inference_basis():
|
||||
def test_inferred_is_decided_by_entailment_engine_with_oracle_agreement():
|
||||
response = _run("inferred-from-bounded-evidence")
|
||||
assert response["assigned_state"] == "inferred"
|
||||
assert response["decision_reason"] == "bounded_inference_from_evidence"
|
||||
assert response["inference_basis"] == ["ev-c1-branch-from-main", "ev-c1-tag-on-main"]
|
||||
assert response["decision_reason"] == "entailed_from_resolved_premises"
|
||||
assert response["inference_basis"] == [
|
||||
"ev-c1-branch-from-main",
|
||||
"ev-c1-rule-reachability",
|
||||
"ev-c1-tag-on-main",
|
||||
]
|
||||
assert response["evidence_ledger"] == response["inference_basis"]
|
||||
|
||||
inference = response["trace_summary"]["inference"]
|
||||
assert inference["consulted"] is True
|
||||
assert inference["outcome"] == "entailed"
|
||||
assert inference["reason"] == "tautological_implication"
|
||||
assert inference["oracle_verdict"] == "entailed"
|
||||
assert inference["engine_oracle_agreement"] is True
|
||||
# The ROBDD proof evidence is present: the implication check canonicalized
|
||||
# to the tautology node.
|
||||
assert inference["entailment_trace"]["entailment_check_key"] == "T"
|
||||
|
||||
# Both deciders appear in the authority path only because they were consulted.
|
||||
assert "generate.proof_chain.entail.evaluate_entailment_with_trace" in (
|
||||
response["authority_path"]
|
||||
)
|
||||
assert "evals.deductive_logic.oracle.oracle_entailment" in response["authority_path"]
|
||||
|
||||
|
||||
def test_unrelated_premise_cannot_mint_inferred():
|
||||
# The hazard this leg exists to prevent: a claim with no support, citing a
|
||||
# resolvable but logically UNRELATED record as a premise, must not be
|
||||
# assigned `inferred`. The engine decides `unknown`; the state falls to
|
||||
# `undetermined`.
|
||||
response = _run("unrelated-premise-still-undetermined")
|
||||
assert response["assigned_state"] == "undetermined"
|
||||
assert response["decision_reason"] == "insufficient_evidence"
|
||||
inference = response["trace_summary"]["inference"]
|
||||
assert inference["consulted"] is True
|
||||
assert inference["outcome"] == "unknown"
|
||||
assert inference["oracle_verdict"] == "unknown"
|
||||
|
||||
|
||||
def test_premises_without_the_rule_do_not_entail():
|
||||
# Dropping the rule record from the premises leaves two atoms that cannot
|
||||
# entail the claim: the engine decides `unknown`, no inferred state.
|
||||
payload = _arguments("inferred-from-bounded-evidence")
|
||||
payload["inference"]["premise_ids"] = ["ev-c1-tag-on-main", "ev-c1-branch-from-main"]
|
||||
response = authority.run_authority(payload)
|
||||
assert response["assigned_state"] == "undetermined"
|
||||
inference = response["trace_summary"]["inference"]
|
||||
assert inference["outcome"] == "unknown"
|
||||
assert inference["engine_oracle_agreement"] is True
|
||||
|
||||
|
||||
def test_engine_oracle_disagreement_refuses(monkeypatch):
|
||||
# Defensive fail-closed: if the independent oracle ever disagreed with the
|
||||
# ROBDD engine, the demo must refuse rather than assign an inferred state.
|
||||
monkeypatch.setattr(authority, "oracle_entailment", lambda premises, query: "unknown")
|
||||
payload = _arguments("inferred-from-bounded-evidence")
|
||||
response = authority.run_authority(payload)
|
||||
assert response["status"] == "refused"
|
||||
assert response["refusal_reason"] == "entailment_oracle_disagreement"
|
||||
assert response["assigned_state"] is None
|
||||
|
||||
|
||||
def test_unconsulted_entailment_engine_not_in_authority_path():
|
||||
response = _run("verified-supported-claim")
|
||||
assert "generate.proof_chain.entail.evaluate_entailment_with_trace" not in (
|
||||
response["authority_path"]
|
||||
)
|
||||
assert response["trace_summary"]["inference"] == {
|
||||
"consulted": False,
|
||||
"detail": "no_inference_block",
|
||||
}
|
||||
|
||||
|
||||
def test_corpus_seal_is_pinned_in_traces():
|
||||
response = _run("verified-supported-claim")
|
||||
assert response["trace_summary"]["corpus_sha256"] == authority.corpus_file_sha256()
|
||||
assert response["trace_summary"]["corpus_id"] == (
|
||||
"demo.epistemic_truth_state.evidence_corpus.v1"
|
||||
)
|
||||
|
||||
|
||||
def test_inference_with_unresolved_premise_does_not_infer():
|
||||
payload = _arguments("inferred-from-bounded-evidence")
|
||||
payload["inference"]["premise_ids"] = ["ev-c1-tag-on-main", "does-not-exist"]
|
||||
response = authority.run_authority(payload)
|
||||
assert response["assigned_state"] == "undetermined"
|
||||
assert response["trace_summary"]["inference"]["detail"] == "premise_unresolved"
|
||||
|
||||
|
||||
def test_undetermined_emits_question():
|
||||
|
|
@ -160,13 +257,18 @@ def test_undetermined_emits_question():
|
|||
assert "insufficient grounded evidence" in response["question"]
|
||||
|
||||
|
||||
def test_scope_boundary_refuses():
|
||||
def test_scope_boundary_refuses_without_consulting_corpus():
|
||||
response = _run("refused-outside-scope")
|
||||
assert response["status"] == "refused"
|
||||
assert response["assigned_state"] == "scope_boundary"
|
||||
assert response["refusal_reason"] == "outside_epistemic_envelope"
|
||||
assert response["decision_reason"] == "outside_epistemic_envelope"
|
||||
assert response["evidence_ledger"] == []
|
||||
# An out-of-envelope claim is refused before the corpus is consulted.
|
||||
assert response["trace_summary"]["evidence_resolution"] == "not_consulted"
|
||||
assert "demos.epistemic_truth_state.authority.resolve_evidence_refs" not in (
|
||||
response["authority_path"]
|
||||
)
|
||||
|
||||
|
||||
def test_proposer_cannot_set_assigned_state():
|
||||
|
|
|
|||
Loading…
Reference in a new issue