fix(demo): keep normative_clearance unassessable for all non-invalid outputs
This demo assigns epistemic truth-state only and runs no normative/ safety/ethics clearance pass, so it has no basis to positively clear a claim. Drop the verified->cleared mapping: verified now reports normative_clearance=unassessable like every other non-invalid output. Updates authority.py, regenerates the affected expected trace hashes, tightens the test (verified asserts unassessable) and adds an invariant test that no non-invalid output is ever cleared, and corrects the README honesty ledger.
This commit is contained in:
parent
a68b7060bd
commit
5306c9f944
4 changed files with 28 additions and 11 deletions
|
|
@ -41,9 +41,10 @@ state is typed
|
|||
|
||||
* It is not the runtime epistemic-state tagger; it is a local demo over fixed
|
||||
fixtures.
|
||||
* It does not run the safety/ethics verdict pass, so `normative_clearance` here
|
||||
reflects only whether CORE positively established the claim (`cleared`) versus
|
||||
did not assess it (`unassessable`). It is **not** a safety guarantee.
|
||||
* It assigns epistemic truth-state only. It runs **no** normative / safety /
|
||||
ethics clearance pass, so `normative_clearance` is `unassessable` on every
|
||||
non-invalid output — including `verified`. This demo never positively clears
|
||||
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.
|
||||
* It does not claim broader epistemic coverage than the small local envelope and
|
||||
|
|
@ -76,7 +77,7 @@ with no proposer-held authority and no execution path.
|
|||
## The six scenarios
|
||||
|
||||
* `verified-supported-claim` — two independent matching records → `verified`,
|
||||
`cleared`, `verified_by_matching_evidence`.
|
||||
`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 →
|
||||
|
|
@ -99,9 +100,9 @@ with no proposer-held authority and no execution path.
|
|||
* 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.
|
||||
* Coarse: `normative_clearance` is a two-state stand-in (`cleared` only for a
|
||||
verified claim, else `unassessable`) because this demo runs no safety/ethics
|
||||
verdict pass.
|
||||
* 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.
|
||||
* Not claimed: runtime integration, serving integration, real evidence
|
||||
retrieval, a safety guarantee, or any coverage beyond this local envelope.
|
||||
|
||||
|
|
|
|||
|
|
@ -351,11 +351,14 @@ def assign_epistemic_state(payload: dict[str, Any]) -> dict[str, Any]:
|
|||
)
|
||||
|
||||
# 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
|
||||
# has no basis to positively clear anything.
|
||||
if len(independent) >= 2:
|
||||
return _assigned(
|
||||
payload,
|
||||
state=EpistemicState.VERIFIED,
|
||||
clearance=NormativeClearance.CLEARED,
|
||||
clearance=NormativeClearance.UNASSESSABLE,
|
||||
decision_reason="verified_by_matching_evidence",
|
||||
evidence_ledger=sorted(record["evidence_id"] for record in independent),
|
||||
trace_summary=trace_summary,
|
||||
|
|
|
|||
|
|
@ -11,12 +11,12 @@
|
|||
"ev-a1-replay",
|
||||
"ev-a1-trace"
|
||||
],
|
||||
"normative_clearance": "cleared",
|
||||
"normative_clearance": "unassessable",
|
||||
"request_id": "demo-eps-a1",
|
||||
"scenario_id": "verified-supported-claim",
|
||||
"status": "assigned",
|
||||
"tool": "core.epistemic_truth_state.review",
|
||||
"trace_hash": "4307277a0f8d8276f29574d934228cc6c74c60fd43c46dba84bffd22d6cdb181",
|
||||
"trace_hash": "1341c27c5906ae528ecc1f0cc4ebd3f71db68f138f6d8365fe0e93dd2d7f7097",
|
||||
"trace_summary": {
|
||||
"authority_evaluated": true,
|
||||
"claim_fingerprint": "cef9198360d02ce3133c1095e776ae86a714fd1c9718aa3576616f935eccdf98",
|
||||
|
|
|
|||
|
|
@ -98,7 +98,9 @@ def test_uses_canonical_epistemic_state_enum():
|
|||
def test_verified_requires_matching_evidence():
|
||||
response = _run("verified-supported-claim")
|
||||
assert response["assigned_state"] == "verified"
|
||||
assert response["normative_clearance"] == "cleared"
|
||||
# This demo runs no normative/safety/ethics clearance pass, so even a
|
||||
# verified claim stays UNASSESSABLE rather than positively cleared.
|
||||
assert response["normative_clearance"] == "unassessable"
|
||||
assert response["evidence_ledger"] == ["ev-a1-replay", "ev-a1-trace"]
|
||||
|
||||
# Drop one independent record: a single supporting record cannot verify.
|
||||
|
|
@ -117,6 +119,17 @@ def test_verified_requires_matching_evidence():
|
|||
assert none_match["decision_reason"] == "insufficient_evidence"
|
||||
|
||||
|
||||
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.
|
||||
for name in SCENARIOS:
|
||||
response = _run(name)
|
||||
if response["status"] == "invalid":
|
||||
assert response["normative_clearance"] is None, name
|
||||
else:
|
||||
assert response["normative_clearance"] == "unassessable", name
|
||||
|
||||
|
||||
def test_evidenced_state_for_single_support():
|
||||
response = _run("evidenced-but-not-verified-claim")
|
||||
assert response["status"] == "assigned"
|
||||
|
|
|
|||
Loading…
Reference in a new issue