Skip to content

refactor(proofs/idris2): drop misleading partial markers (2 of 10 from #89) - #108

Merged
hyperpolymath merged 1 commit into
mainfrom
claude/issue-89-rmo-totality-cleanup
Jun 2, 2026
Merged

refactor(proofs/idris2): drop misleading partial markers (2 of 10 from #89)#108
hyperpolymath merged 1 commit into
mainfrom
claude/issue-89-rmo-totality-cleanup

Conversation

@hyperpolymath

Copy link
Copy Markdown
Owner

Summary

Partial closure of #89 (10 Idris2 partial markers). The two markers in `RMO.idr` are misleading annotations — `secureDelete` and `gdprDelete` are IO computations that exhaust their case-splits and never recurse. IO does not introduce partiality in Idris2 — these are legitimately total. Dropping the `partial` keyword.

Closes 2 of 10

FileFunctionReason it was marked partialNew status
RMO.idr:54`secureDelete`Comment said "Partial because it performs I/O" — but IO does not introduce partialityTOTAL
RMO.idr:139`gdprDelete`(No comment) — but the body is a do-block with exhaustive case-splitTOTAL

What remains (8 markers, all in Composition.idr)

`applyOp` / `applySequence` / `execute` / `undo` / `redo` / `sequenceReversible` / `undoRedoIdentity` / `undoRedoComposition`. These require a real refactor: `applyOp` returns `Filesystem` instead of `Maybe Filesystem`, so operations with unmet preconditions can't be made total without either changing the return type (cascading downstream) or carrying precondition proofs as dependent arguments. Substantive enough for its own track; gated on #70's build oracle landing (#106).

Verification

Locally verified with #105's Model.idr fixes applied:

```
$ idris2 --build proofs/idris2/valence-shell.ipkg
1/4: Building Filesystem.Model OK
2/4: Building Filesystem.RMO (passes both newly-total functions;
fails downstream on pre-existing non-theorem signatures —
#105 territory)
```

Test plan

#89 stays open for the remaining 8 markers.

🤖 Generated with Claude Code

…ecureDelete + gdprDelete (2 of 10 from #89)
Two of the 10 `partial` markers in #89's scope were misleading
annotations: `secureDelete` and `gdprDelete` are IO computations,
exhaust their case-splits, and never recurse. IO does not introduce
partiality in Idris2 — these are legitimately total.
Verified locally with #105's Model.idr fixes applied (post-#105 the
Idris2 build proceeds past both functions without partial-checker
complaint).
The remaining 8 partial markers all live in `Composition.idr`:
- `applyOp` / `applySequence` — partial because operations have
preconditions that aren't represented in the type. Requires a real
refactor to either return `Maybe Filesystem` or carry precondition
proofs as dependent arguments.
- `execute` / `undo` / `redo` — partial because they call `applyOp`;
cascade-cleanup as applyOp becomes total.
- `sequenceReversible` / `undoRedoIdentity` / `undoRedoComposition` —
proof bodies with `?holes`; require closure before totality.
Per #89's resolution: gap-per-PR. The Composition.idr refactor is
substantive enough for its own track and is gated on #70's build
oracle landing (in flight as #106) so each conversion can be machine-
verified.
Closes 2 of 10 markers in #89; #89 stays open for the remaining 8.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@hyperpolymath
hyperpolymath enabled auto-merge (squash) June 1, 2026 21:49
@github-actions

Copy link
Copy Markdown

🔍 Hypatia Security Scan

Findings: 142 issues detected

SeverityCount
🔴 Critical10
🟠 High37
🟡 Medium95

⚠️Action Required: Critical security issues found!

View findings
[
{
"reason": "Workflow executes remote script directly (curl/wget piped to shell). Download, verify checksum/signature, then execute.",
"type": "download_then_run",
"file": "lean-verification.yml",
"action": "verify_download_integrity",
"rule_module": "workflow_audit",
"severity": "high"
},
{
"reason": "Workflow executes remote script directly (curl/wget piped to shell). Download, verify checksum/signature, then execute.",
"type": "download_then_run",
"file": "rust-cli.yml",
"action": "verify_download_integrity",
"rule_module": "workflow_audit",
"severity": "high"
},
{
"reason": "Issue in boj-build.yml",
"type": "missing_timeout_minutes",
"file": "boj-build.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Issue in casket-pages.yml",
"type": "missing_timeout_minutes",
"file": "casket-pages.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Issue in casket-pages.yml",
"type": "missing_timeout_minutes",
"file": "casket-pages.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Issue in cflite_batch.yml",
"type": "missing_timeout_minutes",
"file": "cflite_batch.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Issue in cflite_pr.yml",
"type": "missing_timeout_minutes",
"file": "cflite_pr.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Issue in codeql.yml",
"type": "missing_timeout_minutes",
"file": "codeql.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Issue in compilation_tests.yml",
"type": "missing_timeout_minutes",
"file": "compilation_tests.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Issue in compilation_tests.yml",
"type": "missing_timeout_minutes",
"file": "compilation_tests.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium"
}
]

Powered by Hypatia Neurosymbolic CI/CD Intelligence

hyperpolymath added a commit that referenced this pull request Jun 2, 2026
* fix(licence): prepend SPDX-License-Identifier header to LICENSE
Adds the `SPDX-License-Identifier: MPL-2.0` first-line marker the
estate `check-licence-consistency.sh` governance script requires,
followed by a blank line preserving the existing MPL-2.0 text intact.
Clears `governance / Licence consistency` red inherited by 4 open PRs
(#105, #106, #107, #108).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(proofs): annotate 4 undocumented admits in rmo_operations.v with TRUSTED markers
The estate `check-trusted-base.sh` policy script walks back from each
`Admitted.` line through *consecutive comment lines* (lines whose first
non-whitespace char matches a comment marker `(*` / `*` / `--` / `//` /
`|||` / `#`) and accepts an annotation if a `TRUSTED:` or `AXIOM:` token
appears in that block.
Two prior issues:
1. **Lines 419 + 530** were false-positive markers: the regex
`^[[:space:]]*(Axiom|Admitted|admit\.)` matched the *prose* line
`Admitted pending follow-up. *)` inside a `(* ... *)` comment block
(because after stripping leading whitespace, the line begins with
the keyword `Admitted`). Rewording to `Stub pending follow-up. *)`
eliminates the false positives — now 12 markers total (was 14).
2. **Lines 420 + 531** (now 421 + 533) — the real `Admitted.` lines —
were preceded by `*)` closing-bracket lines that the walker does
NOT recognise as comment lines (no leading `*` / `(*` token), so
it never reached the inline `TRUSTED:` annotation buried deeper
in the comment block.
Fix: prepend a single-line `(* TRUSTED: <rationale> *)` comment
immediately before each `Admitted.`, citing the affected theorem
(`overwrite_pass_equalizes_storage`, `obliterate_not_injective`) and
referring downstream to the preceding model-gap explanation.
Clears `governance / Trusted-base reduction policy` red inherited by
4 open PRs (#105, #106, #107, #108). Underlying model gap (block_overwritten
counter mismatch) remains open as proof debt.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@hyperpolymath
hyperpolymath merged commit 87b5d96 into mainJun 2, 2026
25 of 30 checks passed
@hyperpolymath
hyperpolymath deleted the claude/issue-89-rmo-totality-cleanup branch June 2, 2026 09:30
hyperpolymath added a commit that referenced this pull request Jun 2, 2026
… + Operations.idr type errors (8 of 10 from #89) (#109)
Closes the remaining 8 partial markers in `Composition.idr` (PR #108 was
the first 2 of 10).
## Composition.idr — 8 partial markers dropped
Root cause: `applyOp` called the precondition-requiring wrappers from
`Filesystem.Operations` (mkdir/rmdir/touch/rm/writeFile) which take
`{auto prf : MkdirPrecondition p fs}` etc. No precondition was available
at the call site, making `applyOp` partial. This cascaded to
`applySequence`, `execute`, `undo`, `redo`, and the proofs above them.
Fix: `applyOp` now calls the underlying `addEntry` / `removeEntry` /
`updateEntry` primitives from `Filesystem.Model` directly. The wrappers'
bodies are exactly these primitives, so the behaviour is unchanged.
Precondition-aware variants stay in `Filesystem.Operations` for
theorem-proving contexts; the composition-layer one is the runtime
sequence-application semantics.
With `applyOp` total, the cascade clears:
- `applyOp` / `applySequence` — direct
- `execute` / `undo` / `redo` — cascade (also promoted to `public export`
so their names are visible in subsequent theorem signatures)
- `sequenceReversible` / `undoRedoIdentity` / `undoRedoComposition` —
totality checker accepts the hole-bodied functions (Idris2 0.8.0 does
not reject `?holes` in `total` functions)
## Composition.idr — additional theorem-shape fixes
- `sequenceReversible`: `All (\op => isReversible op = True)` now
imports `Data.List.Quantifiers.All` (the Idris2-0.8.0 location;
`Data.List.All` is deprecated).
- `undoRedoIdentity`: replaced `fromJust $ undo X` (undefined in Idris2
0.8.0 stdlib and partial anyway) with the Maybe-monadic chain
`undo X >>= redo`.
- `undoRedoComposition`: replaced `length undoStack >= n` (a `Bool`,
not a `Type`) with `LTE n (length undoStack)`; reformulated the body
similarly with `>>=` composition.
- `reverseConcat`: body reduced to a hole. The original closed-form
proof relied on `reverse`'s Idris-1-style structural reduction; the
Idris2 0.8.0 tail-recursive `reverse` doesn't unfold the same way.
Needs a different proof strategy (likely `Data.List.reverseOntoSpec`);
parked as a sub-marker under #89.
## Operations.idr — drive-by type-signature fixes
Required to make Operations.idr typecheck so Composition.idr can import
it. Both were pre-existing type errors (not partiality):
- `writeFileReversible`: `old` was a free variable in an auto-implicit
context, creating an unsolvable existential at the call site. Made
`old` an explicit parameter and added the explicit `prfPreserved`
preservation auto-implicit (the inner `writeFile` requires a fresh
preservation proof not in scope at the outer level). The proof body
remains a `?hole` (theorem still to write).
- `operationIndependence`: `(p1 /= p2)` was a `Bool` term in a precondition
position that needs a `Type`. Replaced with `Not (p1 = p2)`. Also added
two more auto-implicit `MkdirPrecondition`s for the post-application
states (mkdir does not automatically preserve `MkdirPrecondition` for
sibling paths — needs a separate lemma).
## Verification
Locally built against #105's Model.idr fixes (RMO temporarily excluded
from ipkg modules list since RMO has additional pre-existing parse
issues at `hardwareEraseIrreversible` not in #89 scope):
```
$ idris2 --build proofs/idris2/valence-shell.ipkg
1/3: Building Filesystem.Model OK
2/3: Building Filesystem.Operations OK
3/3: Building Filesystem.Composition OK
```
No errors, no warnings. `--total` (set in ipkg) verifies all functions
(including the `?hole`-bodied ones) pass the totality checker.
## Closes 8 of 10 from #89
| File | Function | Before | After |
|---|---|---|---|
| Composition.idr | `applyOp` | partial (needs precondition) | TOTAL via Model primitives |
| Composition.idr | `applySequence` | partial (cascade) | TOTAL |
| Composition.idr | `execute` | partial (cascade) | TOTAL + public export |
| Composition.idr | `undo` | partial (cascade) | TOTAL + public export |
| Composition.idr | `redo` | partial (cascade) | TOTAL + public export |
| Composition.idr | `sequenceReversible` | partial (hole body) | TOTAL (hole accepted) |
| Composition.idr | `undoRedoIdentity` | partial (hole body + bad type) | TOTAL (type fixed, hole accepted) |
| Composition.idr | `undoRedoComposition` | partial (Bool/Type mismatch) | TOTAL (type fixed, hole accepted) |
Combined with PR #108 (`secureDelete` + `gdprDelete`), all 10 partial
markers in #89's scope are now resolved. Theorem bodies remain as
`?holes` — that's separate proof debt, not partiality.
#89 can close.
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
hyperpolymath added a commit that referenced this pull request Jun 2, 2026
After PRs #105 / #106 / #108 / #109 admin-merged closing #60 / #61 /
#70 / #89, several files held stale claims:
- PROOF-NEEDS.md: Idris2 listed "23 holes + 8 partial across 4 files"
pre-#108/#109 — partial count is now 0 (10 dropped: 2 in RMO from
IO-totality reclassification, 8 in Composition from primitive-call
refactor). Coq admit detail rewritten: the single_op_reversible
OpRmdir admit was Qed-closed by PR #67 (2026-06-01); 3 new admits
surfaced from PR #55's design-gap pass tracked as #56/#57/#58.
- proofs/idris2/README.md: 21 holes -> 23 holes; "Known oracle status
2026-06-01" -> 2026-06-02, with partial-count reference corrected.
- ROADMAP.adoc: last-refreshed bumped + post-merge attribution.
- CHANGELOG.adoc: new "Added -- 2026-06-02" section recording the
Idris2 cleanup wave + branch sweep + #111 salvage decision.
- .machine_readable/6a2/STATE.a2ml: last-updated 2026-04-19 -> 2026-06-02
(6-week drift); admitted 1 -> 3 with per-admit detail (#56/#57/#58);
session-history bullets added for 2026-06-01 + 2026-06-02.
- 0-AI-MANIFEST.a2ml: last-updated bumped; tests 736 -> 757 (PR #72);
proof-holes-remaining split into coq-admits + idris2 totals.
Issue #111 filed during the sweep for `.github/copilot/coding-agent.yml`
salvaged from the deleted `claude/safedom-res-stale-sweep` branch.
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
hyperpolymath added a commit that referenced this pull request Jun 2, 2026
…marker) (#115)
Closes the parked `?reverseConcatProof` hole from PR #109 (Composition.idr).
The Idris2 0.8.0 stdlib provides:
Data.List.revAppend :
(vs, ns : List a) -> reverse ns ++ reverse vs = reverse (vs ++ ns)
Which is exactly our claim, modulo direction of the equation. Applying
`sym` flips it to the conventional "concatenation distributes over
reverse" framing used by our local theorem:
reverseConcat xs ys : reverse (xs ++ ys) = reverse ys ++ reverse xs
reverseConcat xs ys = sym (revAppend xs ys)
The previous closed-form proof using induction + `rewrite` failed under
Idris2 0.8.0 because the stdlib's `reverse` is tail-recursive via
`reverseOnto`, and so does not structurally reduce per the Idris-1-style
expansion `reverse (x :: xs) = reverse xs ++ [x]`. Delegating to the
stdlib lemma is both shorter and more robust.
Verified locally with the full stacked context (#105 + #108 + #109 +
hardware-erase + audit-entry fixes + RMO overwriteIrreversible /
auditTrailCompleteness drive-bys for build progression). All 4 modules
build clean.
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@hyperpolymath