Commit b1bdd6b
proof(SafeYAML): annotate 4 bodyless decls as OWED (Refs standards#158) (#48)
## Summary
Converts the four bodyless declarations in
`src/Proven/SafeYAML/Proofs.idr` from terse `Postulate:` comments to the
estate's OWED-with-justification convention established 2026-05-20
across SafeChecksum / Buffer / CryptoAccel / HKDF / Bloom / FPGA and the
SafeAPIKey / SafeCORS / SafeCSV / SafeSemVer / SafeHtml sibling PRs
(#37/#38/#39/#40/#41):
- Triple-pipe `|||` doc-comment stating the claim
- `0 ` (erased multiplicity) so the postulate is not runtime-callable
- Bare signature, no `postulate` keyword
- Explicit Idris2 0.8.0 blocker + discharge condition
Refs hyperpolymath/standards#158.
## The four OWED items
### `standardTagsSafe`
**Claim:** any `tag` that is one of the seven standard YAML tags
(`!!null` / `!!bool` / `!!int` / `!!float` / `!!str` / `!!seq` /
`!!map`) is not in `dangerousTags`, so `isDangerousTag tag = False`.
**Why OWED:** Witnessed by inspection of the `dangerousTags` list, which
contains only language-specific object-instantiation tags. Held back by
Idris2 0.8.0 not reducing `elem` over abstract `String` at the type
level — `prim__eq_String` is FFI-bound, so `tag \`elem\` dangerousTags`
will not reduce to `False` by Refl even given the standard-tags
hypothesis. Same blocker family as SafeChecksum's Luhn/ISBN String-FFI
OWED set and the boj-server `charEqSym` class-J axiom.
**Discharge:** a `Data.String` reflective tactic (or a `DecEq String`
lemma over the two literal lists), or refactor to a `YAMLTag` enum where
decidable equality reduces by Refl.
### `secureDefaultsBlockDangerous`
**Claim:** `isDangerousTag tag = True` implies `isBlockedTag
secureDefaults tag = True`.
**Why OWED — TWO compounding gaps:**
1. **Load-bearing caveat:** the equivalence is presently NOT total in
the source. `dangerousTags` lists 14 tags but
`secureDefaults.blockedTags` lists only 9. Five entries are missing from
`blockedTags`: `!!ruby/object:Gem::Installer`,
`!!ruby/object:Gem::SpecFetcher`, `!!ruby/object:Gem::Requirement`,
`tag:yaml.org,2002:ruby/object`, `tag:yaml.org,2002:java/object`. The
OWED therefore packages two unblockings rather than glossing over this.
2. **`elem` Refl gap:** same blocker family as `standardTagsSafe` —
`prim__eq_String` does not type-level reduce, so neither `tag \`elem\`
dangerousTags` nor `tag \`elem\` opts.blockedTags` normalise to a
definite Bool for an unknown `tag`.
**Discharge:** (a) widen `secureDefaults.blockedTags` to be a true
superset of `dangerousTags` (Types-side fix), AND (b) a `Data.String`
reflective tactic or a `DecEq String`-driven `elem`-monotonicity lemma.
Or refactor to a `YAMLTag` enum.
### `isScalarCorrect`
**Claim:** `isScalar` and `isCollection` are complementary, i.e.
`isScalar val = True` implies `not (isCollection val) = True`.
**Why OWED:** Witnessed by `isCollection = not . isScalar` in
`Proven.SafeYAML.Types`, so the goal is `Bool` double-negation. Held
back by Idris2 0.8.0 not reducing `not . not . isScalar val` to
`isScalar val` by Refl when `val` is abstract — the composition needs
Idris to split on `val`'s constructor before either `not` can fire. Same
blocker family as the `Data.Bool` involution gap noted in SafeChecksum's
`xorChecksum [x,x] = 0` OWED.
**Discharge:** case-analysis on the nine `YAMLValue` constructors (each
branch reduces to `not (not True) = True` by Refl), or a
`boolDoubleNegation` lemma over `Bool`.
### `parsingNeverCrashes`
**Claim:** for every `input` and `opts`, `parseYAMLWith opts input`
reduces to either `Err err` for some `YAMLError err` or `Ok val` for
some `YAMLValue val` — parsing is exception-free.
**Why OWED — TWO compounding gaps:**
1. The in-module `parseYAMLWith` here is a stub returning `Ok YNull` —
the real parser lives outside this proof module and is not yet imported.
An honest discharge waits for the production parser hookup.
2. Even with the stub, the trivial witness `Right (YNull ** Refl)` would
be a no-op against the production parser. Same shape as SafeChecksum's
`verifyCRC32Definition` (definitional unfolding) but blocked on the
real-parser wire-up rather than the FFI seam.
**Discharge:** import the real `Proven.SafeYAML.parseYAML` (or its
`*With` variant), establish totality of its return-pattern, then
structurally `Right (val ** Refl)` over the parser's case-tree.
## Safety posture
- Zero `believe_me`
- Zero `postulate`
- Zero `idris_crash`
- All `0 `-erased — postulates cannot leak into runtime
- Discoverable as named declarations (vs silent / commented-out)
## Test plan
- [ ] Idris2 0.8.0 `--check` on `src/Proven/SafeYAML/Proofs.idr` once
estate base-package dependency resolution is unjammed — local `idris2
--build proven.ipkg` currently fails with `Required base >= 0.6.0 but no
matching version is installed` (estate-wide CI jam, same as SafeHtml PR
#41 — DRAFT until then)
- [ ] Verify no downstream module shadows the four names (grep was clean
at edit time)
- [ ] Owner review of OWED reasons against SafeChecksum precedent
- [ ] Decide whether `secureDefaultsBlockDangerous`'s "widen
`blockedTags`" arm should land as a separate `Types.idr` fix before the
proof discharge, or as a joint PR
Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>1 parent f3ebd99 commit b1bdd6b
1 file changed
Lines changed: 102 additions & 26 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
82 | 82 | | |
83 | 83 | | |
84 | 84 | | |
85 | | - | |
86 | | - | |
87 | | - | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
88 | 104 | | |
89 | | - | |
90 | | - | |
91 | | - | |
92 | | - | |
93 | | - | |
94 | | - | |
95 | | - | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
96 | 138 | | |
97 | | - | |
98 | | - | |
99 | | - | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
100 | 142 | | |
101 | 143 | | |
102 | 144 | | |
| |||
185 | 227 | | |
186 | 228 | | |
187 | 229 | | |
188 | | - | |
189 | | - | |
190 | | - | |
191 | | - | |
| 230 | + | |
| 231 | + | |
| 232 | + | |
| 233 | + | |
| 234 | + | |
| 235 | + | |
| 236 | + | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
| 242 | + | |
| 243 | + | |
| 244 | + | |
| 245 | + | |
| 246 | + | |
| 247 | + | |
| 248 | + | |
192 | 249 | | |
193 | | - | |
194 | | - | |
195 | | - | |
| 250 | + | |
| 251 | + | |
| 252 | + | |
196 | 253 | | |
197 | 254 | | |
198 | 255 | | |
| |||
202 | 259 | | |
203 | 260 | | |
204 | 261 | | |
205 | | - | |
206 | | - | |
207 | | - | |
| 262 | + | |
| 263 | + | |
| 264 | + | |
| 265 | + | |
| 266 | + | |
| 267 | + | |
| 268 | + | |
| 269 | + | |
| 270 | + | |
| 271 | + | |
| 272 | + | |
| 273 | + | |
| 274 | + | |
| 275 | + | |
| 276 | + | |
| 277 | + | |
| 278 | + | |
| 279 | + | |
| 280 | + | |
| 281 | + | |
| 282 | + | |
| 283 | + | |
208 | 284 | | |
209 | | - | |
210 | | - | |
211 | | - | |
| 285 | + | |
| 286 | + | |
| 287 | + | |
212 | 288 | | |
213 | 289 | | |
214 | 290 | | |
| |||
0 commit comments