proof(SafeJson): fix appendLengthInc so the module compiles (completes #138)#144
Conversation
…LengthInc; make path accessors total Completes the work of PR #138, verified end-to-end against a clean Idris2 0.8.0 + contrib toolchain (idris2 --check builds all 5 SafeJson modules with 0 errors). Discharges two SafeJson.Proofs OWEDs: - anyMatchesTAny: 6-arm case-split on JsonValue; each concrete head reduces through the catch-all `matchesType _ TAny = True` by Refl (matchesType stays `covering` — a concrete head per arm is enough). - singleKeyPath: with-pattern on `lookup k obj`, both arms by Refl (Maybe-identity). Two corrections PR #138 as-authored required but missed: 1. getPath / getSegment are made `total` in SafeJson.Access. They were `covering` via the module `%default covering` (contrary to the PR's claim that they were already total). Idris2 0.8.0 does not reduce `covering` definitions during proof conversion, so singleKeyPath cannot discharge while they remain covering — reverting the annotation reproduces the `singleKeyPath` Mismatch failure. Both are structurally total: getSegment is non-recursive, getPath decreases on the path list. 2. appendLengthInc (from PR #127) had its `lengthSnoc` arguments swapped. `Data.List.Equalities.lengthSnoc` takes the element first (`lengthSnoc x xs`), so `lengthSnoc arr v` does not type-check under Idris2 0.8.0 contrib. This pre-existing error blocks the entire SafeJson.Proofs module from compiling on main, so it had to be fixed for any of these proofs to be checkable. Corrected to `lengthSnoc v arr`. No believe_me / postulate / idris_crash / assert_total introduced. Refs #138, #127, proven#90 #107 #119. https://claude.ai/code/session_01MN5vzRR4MK2dkDNaHqqRDy
…LengthInc fix Aligns this branch with the verified-minimal change set (matching the fix on #138's branch). Supersedes the previous commit, which marked getPath/getSegment `total` and claimed that annotation was required for singleKeyPath to discharge. That claim was wrong. Verified against a clean Idris2 0.8.0 + contrib toolchain: with appendLengthInc fixed, SafeJson.Proofs type-checks with getPath/getSegment left `covering` (the module default) — 0 errors across all five SafeJson modules. The covering annotation does not block the clause-level reduction singleKeyPath relies on, so no totality change is needed. Access.idr is therefore reverted to its main state (untouched). The only substantive fix is the one this branch actually needs: appendLengthInc used `lengthSnoc arr v`, but Data.List.Equalities.lengthSnoc is element-first (`lengthSnoc x xs`); `lengthSnoc arr v` fails to type-check under Idris2 0.8.0 contrib and blocks the whole module. Corrected to `lengthSnoc v arr`. Proof comments for singleKeyPath and anyMatchesTAny corrected to match (no false "they are total" claim), and stale /tmp/ scratch-path references removed. No believe_me / postulate / idris_crash / assert_total introduced. Refs #138, #127, proven#90 #107 #119. https://claude.ai/code/session_01MN5vzRR4MK2dkDNaHqqRDy
|
|
📌 Systemic finding (filing here — repo Issues are disabled). This PR fixes a one-line proof bug, but that bug reaching 1.
|
|
Correction to my comment just above: repo Issues are not disabled — I've filed the systemic finding as #145. Please track the CI-gating discussion there; the comment above is superseded by that issue. Generated by Claude Code |
…gating finding - discharged-decls 34 -> 36 (anyMatchesTAny, singleKeyPath via #144) - last-updated -> 2026-05-31 - session-history: appendLengthInc root cause (contrib lengthSnoc is element-first; #127's `lengthSnoc arr v` blocked the whole SafeJson.Proofs module) + the #145 CI-gating finding. https://claude.ai/code/session_01MN5vzRR4MK2dkDNaHqqRDy
🔍 Hypatia Security ScanFindings: 321 issues detected
View findings[
{
"reason": "Action perpolymath/standards/.github/workflows/governance-reusable.yml@main\n needs attention",
"type": "unpinned_action",
"file": "governance.yml",
"action": "pin_sha",
"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 dogfood-gate.yml",
"type": "missing_timeout_minutes",
"file": "dogfood-gate.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Issue in dogfood-gate.yml",
"type": "missing_timeout_minutes",
"file": "dogfood-gate.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Issue in dogfood-gate.yml",
"type": "missing_timeout_minutes",
"file": "dogfood-gate.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Issue in dogfood-gate.yml",
"type": "missing_timeout_minutes",
"file": "dogfood-gate.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium"
}
]Powered by Hypatia Neurosymbolic CI/CD Intelligence |
## Summary Addresses the source-fixable half of #145. Adds a dedicated **`proof-check`** job to `idris2-ci.yml` that type-checks **every** `src/**/Proofs.idr` (glob-discovered, so new proof files are auto-covered) with `idris2 -p contrib -p network --check`, running in parallel with the slow full `build`. ## Why #127's swapped-arg `appendLengthInc` (`lengthSnoc arr v` — but contrib `lengthSnoc` is element-first) failed to type-check and blocked the **entire** `SafeJson.Proofs` module, yet reached `main`. Two gaps let it through: 1. The only job compiling proof modules was the full `idris2 --build proven.ipkg` (~12-20 min warm) — manual merges routinely outrace it while it sits `queued`. 2. The explicit per-module `--check` list in `idris2-ci.yml` covered **zero** `Proofs.idr` files — exactly the modules the Phase-3 discharge campaign edits each PR. ## What it does - New `proof-check` job: globs `find src -name 'Proofs.idr'`, checks each, emits `::error file=…::` annotations, fails if any fail. - Caches only the Idris2 compiler; **never** `idris2 --install proven.ipkg`, **never** caches `build/` — so a stale cache cannot mask a source-level break. - Documents the decision as **ADR-004** in `META.a2ml`. ## Remaining (admin, tracked in #145) This job is necessary but not sufficient. Closing the gate needs `proof-check` made a **required status check** on `main` via branch protection — only the repo admin can toggle that. Until then, "merged" still doesn't imply "CI passed" under the solo-admin-merge posture. ## Verification - Both files parse (`yaml.safe_load` → jobs `build, proof-check, docs`; `tomllib` → ADR-001..004). - The `Proofs.idr` check loop was validated locally on a clean idris2-0.8.0 + contrib install (SafeJson/SafeMath/SafeString proof cones, 0 errors). - This PR touches `idris2-ci.yml`, which is in the CI path filter — so the new `proof-check` job runs on this PR and proves itself before merge. Refs #145, #144, #127. --- _Generated by [Claude Code](https://claude.ai/code/session_01MN5vzRR4MK2dkDNaHqqRDy)_ Co-authored-by: Claude <noreply@anthropic.com>



Summary
Completes the work of #138, verified end-to-end against a clean Idris2 0.8.0 + contrib toolchain. Discharges the two
SafeJson.ProofsOWEDs #138 targeted, and fixes the pre-existing bug that was actually preventing the module from compiling.idris2 --check src/Proven/SafeJson/Proofs.idrbuilds all 5 modules (Core → Parser → Access → SafeJson → Proofs) with 0 errors (one pre-existing unreachable-clause warning inAccess, also present onmain).What it discharges
anyMatchesTAny— 6-arm case-split onJsonValue; for each concrete head every earlier clause demands a non-TAnysecond argument, so each arm reduces to the catch-allmatchesType _ TAny = TruebyRefl. No totality change needed.singleKeyPath—with-pattern onlookup k obj, both arms byRefl(Maybe-identity).The actual blocker:
appendLengthInc(from #127)Data.List.Equalities.lengthSnocis element-first (lengthSnoc x xs), so the existinglengthSnoc arr vdoes not type-check under Idris2 0.8.0 contrib (Mismatch: JsonValue vs List ?a). Because it fails to elaborate, it blocks the entireSafeJson.Proofsmodule — so none of its proofs (including #138's two new ones) were checkable. Fixed tolengthSnoc v arr.This is the failure #138's description attributed to "a local contrib quirk [that] does NOT reproduce in CI." It is not local — it reproduces on a clean v0.8.0 install, which also means
main's ownidris2 --build proven.ipkgcurrently fails at this module. This PR fixes that.Correction to an earlier version of this PR
An earlier push on this branch also marked
getPath/getSegmenttotaland claimed that annotation was required forsingleKeyPathto discharge. That claim was wrong and has been reverted. Verified: withappendLengthIncfixed,SafeJson.Proofschecks cleanly while those accessors staycovering(the%defaultinAccess.idr). The covering annotation does not block the clause-level reduction the proof relies on, so no totality change is needed andAccess.idris left untouched. The change set is nowProofs.idronly.Verification (clean idris2 0.8.0, contrib + network)
idris2 --check src/Proven/SafeJson/Proofs.idr— all 5 modules, 0 errors,AccessleftcoveringlengthSnocfix reproduces theappendLengthIncMismatchtotalannotation is not needed (covering + fix compiles clean) — hence droppedbelieve_me/postulate/idris_crash/assert_totalRelationship to #138
#138 is closed; its branch already carries this same minimal fix. This PR (on the development branch) is the canonical, CI-running version.
Refs #138, #127, proven#90 #107 #119.
Generated by Claude Code