proof(lean4): mechanize Capability Soundness + Ethical Verdict Consistency - #44
Merged
Merged
Conversation
…m 2) Make the informal "by inspection of execution paths" argument for Theorem 2 machine-checked, reusing the real PhrAction AST. * Model: Resource / Operation / Capability / Context (capability list); requiredCap? maps the four leaf actions to their capability per §2.3 (ACCEPT/REJECT -> route_decision:write, REPORT -> consensus_log:append, EXECUTE f -> module f:exec). * The Executes relation is capability-gated BY CONSTRUCTION: every leaf rule carries the required-capability membership as a hypothesis, and there is deliberately no constructor that executes without an enforcement point. capability_soundness then follows by inversion -- this is exactly "all paths have enforcement points" made formal. * capability_soundness_ite extends enforcement through conditional actions (an executed iteAction reduces to a gated branch). * The two §2.5 side-properties are mechanized too: least_privilege (a fresh context holds only granted capabilities) and no_escalation (a step never enlarges the capability set, S -> S' => S'.caps subset of S.caps). All four are sorry-free; #print axioms reports only Lean's standard propext (capability_soundness_ite is axiom-free). Builds clean on Lean 4.12.0 core, no Mathlib. Docs: safety_proofs.md §2.4 gains a "Mechanized (Lean 4)" note and §5 status table now reads Sandbox Isolation + Capability Soundness = Mechanized (Lean 4), BFT Safety = Model-checked (TLA+/TLC). https://claude.ai/code/session_01DQACj3RFmAPZaBPgR9SAaS
🔍 Hypatia Security ScanFindings: 30 issues detected
View findings[
{
"reason": "Action trufflesecurity/trufflehog@main needs attention",
"type": "unpinned_action",
"file": "secret-scanner.yml",
"action": "pin_sha",
"rule_module": "workflow_audit",
"severity": "high"
},
{
"reason": "Issue in secret-scanner.yml",
"type": "missing_timeout_minutes",
"file": "secret-scanner.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Issue in scorecard-enforcer.yml",
"type": "scorecard_publish_with_run_step",
"file": "scorecard-enforcer.yml",
"action": "split_scorecard_publish_job",
"rule_module": "workflow_audit",
"severity": "high"
},
{
"reason": "binary_to_term without :safe option -- deserialization attack (1 occurrences, CWE-502)",
"type": "elixir_send_unsanitised",
"file": "/home/runner/work/phronesis/phronesis/lib/phronesis/compiler.ex",
"action": "flag",
"rule_module": "code_safety",
"severity": "high"
},
{
"reason": "Nominal-only SAST in phronesis: codeql.yml language matrix contains no language present in the repo and lacks `actions`, so CodeQL records zero results on every commit. Remediation: set the CodeQL matrix to `language: actions`.",
"type": "StaticAnalysis",
"file": "/home/runner/work/phronesis/phronesis",
"action": "auto_fix",
"rule_module": "scorecard",
"severity": "medium",
"remediation": "Add CodeQL or equivalent SAST workflow.",
"scorecard_check": "SAST"
},
{
"reason": "Repository has 3 non-main remote branch(es). Policy: single main branch only.",
"type": "GS007",
"file": ".",
"action": "delete_remote_branches",
"rule_module": "git_state",
"severity": "medium"
},
{
"reason": "Code scanning (Hypatia): hypatia/structural_drift/SD007 -- Hypatia structural_drift: SD007 -- 2 day(s) old",
"type": "CSA001",
"file": ".claude/CLAUDE.md",
"action": "review",
"rule_module": "code_scanning_alerts",
"severity": "medium"
},
{
"reason": "Code scanning (Hypatia): hypatia/structural_drift/SD007 -- Hypatia structural_drift: SD007 -- 2 day(s) old",
"type": "CSA001",
"file": ".claude/CLAUDE.md",
"action": "review",
"rule_module": "code_scanning_alerts",
"severity": "medium"
},
{
"reason": "Code scanning (Hypatia): hypatia/structural_drift/SD007 -- Hypatia structural_drift: SD007 -- 2 day(s) old",
"type": "CSA001",
"file": ".claude/CLAUDE.md",
"action": "review",
"rule_module": "code_scanning_alerts",
"severity": "medium"
},
{
"reason": "Code scanning (Hypatia): hypatia/structural_drift/SD007 -- Hypatia structural_drift: SD007 -- 2 day(s) old",
"type": "CSA001",
"file": ".claude/CLAUDE.md",
"action": "review",
"rule_module": "code_scanning_alerts",
"severity": "medium"
}
]Powered by Hypatia Neurosymbolic CI/CD Intelligence |
Formalize the previously-informal "priority-ordered first match" policy
arbitration (lib/phronesis/state.ex policies_by_priority + the first-match
evaluation in spec/SPEC.core.scm) as the ethics-specific soundness of the
decision procedure, over the real PhrPolicy record.
Model: bestMatch = the highest-priority MATCHING policy, ties broken in
favour of the earlier policy (a fold equivalent to sort-by-priority then
find-first). `matches` abstracts condition evaluation, decoupling
arbitration soundness from the Eval expression semantics.
Theorems (all sorry-free; #print axioms reports only Lean's standard
propext / Quot.sound):
* bestMatch_sound -- a verdict is produced only by a policy that really
matches the situation and is in the policy set
(no spurious verdicts);
* bestMatch_none -- no verdict ⇒ no policy matched; hence
* bestMatch_decisive -- a verdict is produced whenever some policy applies
(the procedure never silently abstains on a live case);
* bestMatch_maximal -- the deciding policy has MAXIMAL priority among all
matching policies, so a higher-priority verdict is
never overridden by a lower-priority one -- e.g. a
high-priority REJECT cannot be undercut by a
lower-priority ACCEPT (the core ethical override).
Builds clean on Lean 4.12.0 core, no Mathlib, no warnings.
Docs: safety_proofs.md gains §2.6 "Ethical Verdict Consistency" with the
mechanization note, and the §5 status table adds the row
"Ethical Verdict Consistency | Mechanized (Lean 4)".
https://claude.ai/code/session_01DQACj3RFmAPZaBPgR9SAaS
🔍 Hypatia Security ScanFindings: 30 issues detected
View findings[
{
"reason": "Action trufflesecurity/trufflehog@main needs attention",
"type": "unpinned_action",
"file": "secret-scanner.yml",
"action": "pin_sha",
"rule_module": "workflow_audit",
"severity": "high"
},
{
"reason": "Issue in secret-scanner.yml",
"type": "missing_timeout_minutes",
"file": "secret-scanner.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Issue in scorecard-enforcer.yml",
"type": "scorecard_publish_with_run_step",
"file": "scorecard-enforcer.yml",
"action": "split_scorecard_publish_job",
"rule_module": "workflow_audit",
"severity": "high"
},
{
"reason": "binary_to_term without :safe option -- deserialization attack (1 occurrences, CWE-502)",
"type": "elixir_send_unsanitised",
"file": "/home/runner/work/phronesis/phronesis/lib/phronesis/compiler.ex",
"action": "flag",
"rule_module": "code_safety",
"severity": "high"
},
{
"reason": "Nominal-only SAST in phronesis: codeql.yml language matrix contains no language present in the repo and lacks `actions`, so CodeQL records zero results on every commit. Remediation: set the CodeQL matrix to `language: actions`.",
"type": "StaticAnalysis",
"file": "/home/runner/work/phronesis/phronesis",
"action": "auto_fix",
"rule_module": "scorecard",
"severity": "medium",
"remediation": "Add CodeQL or equivalent SAST workflow.",
"scorecard_check": "SAST"
},
{
"reason": "Repository has 3 non-main remote branch(es). Policy: single main branch only.",
"type": "GS007",
"file": ".",
"action": "delete_remote_branches",
"rule_module": "git_state",
"severity": "medium"
},
{
"reason": "Code scanning (Hypatia): hypatia/structural_drift/SD007 -- Hypatia structural_drift: SD007 -- 2 day(s) old",
"type": "CSA001",
"file": ".claude/CLAUDE.md",
"action": "review",
"rule_module": "code_scanning_alerts",
"severity": "medium"
},
{
"reason": "Code scanning (Hypatia): hypatia/structural_drift/SD007 -- Hypatia structural_drift: SD007 -- 2 day(s) old",
"type": "CSA001",
"file": ".claude/CLAUDE.md",
"action": "review",
"rule_module": "code_scanning_alerts",
"severity": "medium"
},
{
"reason": "Code scanning (Hypatia): hypatia/structural_drift/SD007 -- Hypatia structural_drift: SD007 -- 2 day(s) old",
"type": "CSA001",
"file": ".claude/CLAUDE.md",
"action": "review",
"rule_module": "code_scanning_alerts",
"severity": "medium"
},
{
"reason": "Code scanning (Hypatia): hypatia/structural_drift/SD007 -- Hypatia structural_drift: SD007 -- 2 day(s) old",
"type": "CSA001",
"file": ".claude/CLAUDE.md",
"action": "review",
"rule_module": "code_scanning_alerts",
"severity": "medium"
}
]Powered by Hypatia Neurosymbolic CI/CD Intelligence |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Two mechanization steps in the proof-completion sequence (sandbox → wire & conformance → mechanise → ethics specifics), both machine-checked in
academic/formal-verification/lean4/Phronesis.leanover the real AST/PhrPolicy, on Lean 4.12.0 core (no Mathlib).1. Capability Soundness (
safety_proofs.md §2, Theorem 2)Turns the informal "by inspection of execution paths" argument into a proof.
capability_soundness— no leaf action executes without the required capability. TheExecutesrelation is capability-gated by construction (every leaf rule carries the required-capability membership; there is no constructor that executes without an enforcement point), so soundness follows by inversion.capability_soundness_ite— enforcement is preserved through conditional actions.least_privilege(§2.5) — a fresh context holds only granted capabilities.no_escalation(§2.5) — a step never enlarges the capability set:S → S' ⟹ S'.caps ⊆ S.caps.2. Ethical Verdict Consistency (
safety_proofs.md §2.6) — the ethics-specific soundnessFormalizes Phronesis's previously-informal priority-ordered first-match policy arbitration (
lib/phronesis/state.expolicies_by_priority+spec/SPEC.core.scm) asbestMatch(highest-priority matching policy, ties to the earlier policy):bestMatch_sound— a verdict comes only from a policy that genuinely matches and is in the set (no spurious verdicts).bestMatch_none/bestMatch_decisive— no verdict ⇒ no policy matched; conversely a verdict is produced whenever some policy applies.bestMatch_maximal— the deciding policy has maximal priority among all matching policies, so a higher-priority verdict is never overridden by a lower-priority one (e.g. a high-priorityREJECTcannot be undercut by a lower-priorityACCEPT— the core ethical override).matchesabstracts condition evaluation, decoupling arbitration soundness from theEvalexpression semantics.Verification
lake buildexit 0, no warnings.sorry-free.#print axiomsreports only Lean's standardpropext(andQuot.soundforbestMatch_maximal) — same trusted base as the existingpreservation/sandbox proofs;capability_soundness_iteis fully axiom-free.Docs
safety_proofs.md§2.4 + new §2.6 gain "Mechanized (Lean 4)" notes; the §5 status table now records Sandbox Isolation, Capability Soundness, and Ethical Verdict Consistency = Mechanized (Lean 4), and BFT Safety = Model-checked (TLA+/TLC).Observations (not in this PR)
lib/phronesis/compiler.exuses:erlang.binary_to_term/1without:safe(CWE-502). Out of scope; flagged for visibility.leanprover/lean-action(SHA-pinned) gate buildingacademic/formal-verification/lean4/— deferred here only because the unauthenticated rate limit blocked fetching a clean pinned SHA this session.https://claude.ai/code/session_01DQACj3RFmAPZaBPgR9SAaS