Proof Portal
jsonparser
ProbeLabs23 findings · 123 requirementsv1.4.0: ArrayEachErr, Escape/SetString, GetArrayLen/GetUint64, DeleteFound, wildcard paths, JSONPath compiler
Owned by Buger
Intent
What this change sets out to do, in the author's words.
Records the v1.4.0 new exported API surface as a FEATURE change so the no_authored_change_surface_reviewed warning clears. New surface traces to SYS-REQ-003/004/008/009/010/014/112/113/114 via source-native // SYS-REQ-xxx code annotations. Adds SYS-REQ-112 (container length accessor), SYS-REQ-113 (wildcard path support), SYS-REQ-114 (JSONPath compiled paths).
Affected requirements
The requirements this change touches — each links to its full page.
In scope (18)
SYS-REQ-003
SYS-REQ-004
SYS-REQ-008
SYS-REQ-009
SYS-REQ-010
SYS-REQ-014
SYS-REQ-033
SYS-REQ-034
SYS-REQ-035
SYS-REQ-048
SYS-REQ-049
SYS-REQ-050
SYS-REQ-056
SYS-REQ-110
SYS-REQ-111
SYS-REQ-112
SYS-REQ-113
SYS-REQ-114
Approvals
Human and AI-agent reviews of the requirements this change moves or scopes — who signed off, and why.
- Claude:spec Conformance · AI agentApprovedAug 20, 2026 · last monthSYS-REQ-048
Show justificationHide justification
deleteFoundConfig resolves the value via internalGetConfig and returns the original input unchanged on any parse error (parser.go:1284-1286). For input truncated at a value boundary (e.g.
{"test":1), the trailing-comma cleanup computes tokEnd=tokenEnd(data[endOffset:]) and short-circuits withif endOffset+tokEnd >= len(data) { return data, false }(parser.go:1291), so no out-of-range index or slice is taken and the caller's bytes are returned as-is. The deep_spec truncation cases and MCDC Row5 witness confirm no panic and original-input return. - Claude:spec Conformance · AI agentApprovedAug 20, 2026 · last monthSYS-REQ-049
Show justificationHide justification
Every internalGetConfig call in the delete path checks the returned error and short-circuits to the safe fallback
return data, falserather than proceeding with the returned offsets: the parent-path lookup (parser.go:1270-1273), the value-span lookup in the object branch (parser.go:1284-1286), and the full-path lookup in the array branch (parser.go:1320-1323). No branch discards the error and continues with the offsets, so invalid offsets can never drive the copy/slice at parser.go:1380-1382. MCDC Row3 propagated-error witness passes. - Claude:spec Conformance · AI agentApprovedAug 20, 2026 · last monthSYS-REQ-050
Show justificationHide justification
For an array-element path (last key
[N]) the array branch calls internalGetConfig with the full key list and returns the original input on error (parser.go:1320-1323); a truncated array such as{"a":[1,2yields MalformedArrayError from blockEnd, so the untouched payload is returned. Even when a truncated element resolves at end-of-input, the trailing-comma cleanup guards withendOffset+tokEnd >= len(data)before any deref (parser.go:1328), again returning data unchanged. No unchecked index is taken, so no panic. MCDC Row5 truncated-array witness passes. - Claude:spec Conformance · AI agentApprovedAug 20, 2026 · last monthSYS-REQ-056
Show justificationHide justification
Delete resolves the target via internalGetConfig, and when the addressed value is truncated mid-structure (e.g. '{"a":{"b":1') that call returns an error and deleteFoundConfig returns the original data slice unchanged with found=false (parser.go:1283-1286); the tokenEnd sentinel path also returns data unchanged when no trailing delimiter is found (parser.go:1291-1294). Delete() discards the found flag and returns that unchanged payload, and all subsequent index math is bounds-checked, so no panic occurs. The five MCDC rows and TestDeleteTruncatedMidStructure confirm unchanged output and no panic.
- Claude:spec Conformance · AI agentApprovedAug 20, 2026 · last monthSYS-REQ-004
Show justificationHide justification
GetFloat meets !addressed_value_is_number | !raw_number_token_is_float_parseable | returns_getfloat_value: non-Number types error out with no value, and a Number token is returned via ParseFloat(v), which returns MalformedValueError when parseFloat fails (the !float_parseable disjunct). The ArrayEachErr aspect in the description also holds: arrayEachErr increments count BEFORE invoking the callback, so a callback that stops via io.EOF (graceful, nil error) or any other error returns a count that includes the stopping element — TestArrayEachErr confirms count==2 on EOF-at-2 and count==3 on error-at-3.
- Claude:spec Conformance · AI agentApprovedAug 20, 2026 · last monthSYS-REQ-008
Show justificationHide justification
EachKey satisfies the multipath contract: it only fires cb(pi, v, dt, e) for a path that fully matches at the current level (len(p)==level, unused pathFlags, equalStr key match, sameTree ancestry), so missing paths emit no found-value callback; malformed input drives cb(-1,nil,Unknown,MalformedJsonError) and returns -1; and the i<ln loop completes the requested scan, returning early only once pathsMatched==len(paths). The empty-key-component panic (KI-1) is fixed here — the level<1 guard (line 708) and the len(p[level])==0 guard (line 775) prevent the out-of-range dereference, and KI-1 status is 'fixed'. TestEachKey and TestEachKeyEmptyKeyPathComponent confirm dispatch and the no-callback-on-empty-component behavior.
- Claude:spec Conformance · AI agentApprovedAug 20, 2026 · last monthSYS-REQ-033
Show justificationHide justification
The formula requires that Delete with a provided path whose target exists returns the document with that target removed. Delete (parser.go:1238) calls deleteFoundConfig, which for an existing object key computes keyOffset/endOffset via findKeyStartConfig+internalGetConfig and splices out the element plus its trailing comma (parser.go:1276-1317). Correctness is witnessed strongly: TestMCDC_SYS_REQ_033_Row3 deletes
afrom{"a":1,"b":2}and asserts Get(result,"a") is KeyPathNotFoundError, and the reference oracle (reference_oracle_test.go:704 @TestOracleDeleteCorrectness) runs 10000 randomized deletes asserting the removed path is gone and residual JSON stays valid. - Claude:spec Conformance · AI agentApprovedAug 20, 2026 · last monthSYS-REQ-034
Show justificationHide justification
The formula requires that Delete with a provided path, an absent target, and otherwise-usable input returns the original payload unchanged. In deleteFoundConfig the findKeyStartConfig KeyPathNotFoundError branch (parser.go:1277) returns
data, false— the untouched input slice — so a missing key yields the original bytes. TestMCDC_SYS_REQ_034_Row2/Row3 and TestObligation_SYS_REQ_034 confirmDelete({"a":1},"missing")equals the input, TestPropertyDeleteIdempotent proves idempotence, and TestOracleDeleteCorrectness asserts the input is unchanged across 10000 random deletes. KI-1 (empty-key panic) is status:fixed and the len(keys[lk-1])>0 guard at parser.go:1260 plus TestDeleteEmptyKeyPathComponent lock in panic-free degradation. - Claude:spec Conformance · AI agentApprovedAug 20, 2026 · last monthSYS-REQ-035
Show justificationHide justification
The formula requires that on malformed/truncated/unusable input Delete returns the original payload unchanged AND does not panic. deleteFoundConfig returns
data, falseon every parse failure path — internalGetConfig error (parser.go:1270,1284,1320) and the truncation sentinelendOffset+tokEnd >= len(data)(parser.go:1291,1328) — and the trailing-comma cleanup is fronted by prevTok>-1 / bounds guards (parser.go:1291-1317,1370) so no data[-1] deref occurs. TestMCDC_SYS_REQ_034_Row4 ({"a":) and TestDeleteEmptyKeyPathComponent assert unchanged output with runNoPanic, and the KI-1 fix (status:fixed) added the seven len()>0 guards that keep empty-key components panic-free. The oracle harness wraps Delete in a recover() and saw zero panics over 10000 inputs. - Claude:spec Conformance · AI agentApprovedAug 20, 2026 · last monthSYS-REQ-003
Show justificationHide justification
GetInt satisfies !addressed_value_is_number | !raw_number_token_is_integer_parseable | returns_getint_value: it rejects non-Number types with an error (no value) and otherwise returns ParseInt(v), which yields OverflowIntegerError/MalformedValueError on non-parseable tokens (the !integer_parseable disjunct) and the int64 on success. The GetUint64 variant described in the requirement correctly maps non-negative in-range values, returns MalformedValueError for negatives (n<0) and non-integers, and OverflowIntegerError when strconv.ParseUint reports ErrRange. TestGetUint64 exercises zero, max uint64, max-uint64+1 (overflow), and negative (malformed) boundaries.
History
This change's decision lineage — who did what, when. Most recent first.
- CreatedBugerJul 28, 2026 · 2 months ago
Change history
Every recorded revision of this change's source file — newest first, each with its commit message and the diff for that change.