Proof Portal

Projects

jsonparser

ProbeLabs23 findings · 123 requirements
All changes
ChangeCHG-260728-RKTSFeatureActive

v1.4.0: ArrayEachErr, Escape/SetString, GetArrayLen/GetUint64, DeleteFound, wildcard paths, JSONPath compiler

Owned by Buger

Active feature change scoped to 18 requirements.

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.

Approvals

Human and AI-agent reviews of the requirements this change moves or scopes — who signed off, and why.

  1. Claude:spec Conformance · AI agentApprovedAug 20, 2026 · last month
    SYS-REQ-048
    Show 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 with if 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.

  2. Claude:spec Conformance · AI agentApprovedAug 20, 2026 · last month
    SYS-REQ-049
    Show justification

    Every internalGetConfig call in the delete path checks the returned error and short-circuits to the safe fallback return data, false rather 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.

  3. Claude:spec Conformance · AI agentApprovedAug 20, 2026 · last month
    SYS-REQ-050
    Show 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,2 yields MalformedArrayError from blockEnd, so the untouched payload is returned. Even when a truncated element resolves at end-of-input, the trailing-comma cleanup guards with endOffset+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.

  4. Claude:spec Conformance · AI agentApprovedAug 20, 2026 · last month
    SYS-REQ-056
    Show 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.

  5. Claude:spec Conformance · AI agentApprovedAug 20, 2026 · last month
    SYS-REQ-004
    Show 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.

  6. Claude:spec Conformance · AI agentApprovedAug 20, 2026 · last month
    SYS-REQ-008
    Show 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.

  7. Claude:spec Conformance · AI agentApprovedAug 20, 2026 · last month
    SYS-REQ-033
    Show 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 a from {"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.

  8. Claude:spec Conformance · AI agentApprovedAug 20, 2026 · last month
    SYS-REQ-034
    Show 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 confirm Delete({"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.

  9. Claude:spec Conformance · AI agentApprovedAug 20, 2026 · last month
    SYS-REQ-035
    Show justification

    The formula requires that on malformed/truncated/unusable input Delete returns the original payload unchanged AND does not panic. deleteFoundConfig returns data, false on every parse failure path — internalGetConfig error (parser.go:1270,1284,1320) and the truncation sentinel endOffset+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.

  10. Claude:spec Conformance · AI agentApprovedAug 20, 2026 · last month
    SYS-REQ-003
    Show 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.

  1. 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.