docs: hold DLEAPP artifact claims to the sourced-evidence standard - #48
Merged
Conversation
Applies fixes from an audit of all 34 artifact files (43 findings). Citations were added only where a source was verified to support the specific claim; everything else was reworded to what the code shows. The dominant defect was ELSE-branch assertion: stating a specific meaning for a missing, NULL or unresolved value. Three of the four conversation views asserted a message direction on rows where none was established: - discordMessages labeled every message 'Received' whenever the signed-in account id could not be resolved. - whatsappMessages labeled system entries 'Incoming'. - wireIndexedDb labeled sender-less events (conversation-created, member events) as received. All three now emit a blank direction, matching signalMessages, which already handled this correctly. signalMessages reported 'File not in extraction' for what are eight distinct failure paths in decrypt_attachment. Only four are distinguishable from the call site, so it now reports those four and collapses the rest into 'Could not decrypt' rather than asserting a cause it cannot tell apart. Completeness claims were corrected where the code contradicted them (discordCacheRecords excludes bundle assets; discordUsers only sees accounts in the endpoints it decodes) and left where they are scoped to a container and accurate. Also: UDMUX addresses no longer labeled 'Public Server'; Roblox log timestamps no longer asserted as UTC; a DPAPI header no longer claimed without validating the provider GUID; Roblox WebView2 user-id attribution fallback disclosed; wireCookies switched to the read-only sqlite helper; Wire service-worker encryption note applied only to resolved asset rows. Verified empirically rather than assumed: the WhatsApp system-message discriminator against the local corpus (an alternative candidate was tested and rejected), and Wire's MLS created_at unit, which was already correct and needed no change. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
stark4n6
pushed a commit
to stark4n6/DLEAPP
that referenced
this pull request
Aug 5, 2026
Adds admin/scripts/check_claim_language.py, ported from the canonical iLEAPP implementation, and wires it into the existing lint workflow as an added step in the same job. The check reads each scripts/artifacts/*.py module with ast, evaluates its __artifacts_v2__ literal, and matches the name and description of every entry against a vocabulary of phrasing that past audits found to assert what the parsed data does not establish: completeness words, attributions of an act to "the user", certainty words. Those two fields reach the examiner through the HTML report and the LAVA manifest, so a claim there is quoted in casework; PR abrignoni#48 fixed them by hand and nothing has watched them since. It also fails on a stale allowlist entry, so an entry cannot outlive the description it was written for and silently shield the next claim under the same key, and prints NOT CHECKED modules on every run so the coverage hole stays visible rather than being assumed empty. Ten fields fired on first run. Nine are reworded to what the data shows; in each the trigger word was removable without losing information -- three cases of "complete <value>" describing one column, six leading "All"/"Every" over a set the following clause already scopes. The tenth is allowlisted: discordCacheRecords' match is inside its own hedge ("a partial record ... rather than a complete one"). Known coverage gap, documented in the docstring: robloxWindows.py builds __artifacts_v2__ through a helper rather than a literal, so its four Windows artifacts are not read. Their descriptions are inherited from the macOS modules, which are checked. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Applies fixes from an audit of all 34 DLEAPP artifact files (43 findings: 17 moderate, 26 minor). Citations were added only where a source was verified to support the specific claim; everything unverifiable was reworded to what the code and data show.
The main finding was not what the scan predicted
A vocabulary scan had flagged 10 completeness claims ("Every Discord account…", "All structured Roblox Player log events…"). On reading the code, only two were indefensible — the rest are scoped to a container and accurate. The larger and more repeated problem was ELSE-branch assertion: stating a specific meaning for a missing, NULL or unresolved value.
Three of the four conversation views asserted a message direction on rows where none was established:
discordMessageslabeled every message "Received" whenever the signed-in account id could not be resolved (no Sentry scope, no Local Storage).whatsappMessageslabeled system entries "Incoming".wireIndexedDblabeled sender-less events (conversation-created, member events — kinds the artifact deliberately includes) as received.All three now emit a blank direction.
signalMessagesalready did this correctly and was the in-repo model.signalMessagesreported "File not in extraction" for what are eight distinct failure paths indecrypt_attachment— including a missing decryption key. Only four are distinguishable from the call site, so it now reports those four ("Attachments folder not in extraction", "No key recorded", "No stored path recorded", "File not in extraction") and collapses the indistinguishable remainder into "Could not decrypt" rather than asserting a cause.Verified empirically rather than assumed
ZMESSAGETYPE6 is 265 rows, all withZISFROMMEclear and all in group chats. An alternative discriminator (ZGROUPEVENTTYPE) was tested and rejected — it is populated on ordinary messages too.created_atfor MLS identity was checked against sample data (10-digit value resolving to 2026, not 1970). It was already correct; no change made, unit recorded.Other corrections
Roblox
UDMUX Address/Portno longer labeled "Public Server"/"Public Port" (the file's own notes decline to guarantee that relationship); Roblox log timestamps no longer asserted as UTC when the parser returns naive datetimes for lines without an offset; a Roblox WebView2 column no longer claims "DPAPI Header" without validating the provider GUID; the WebView2 user-id attribution fallback (which can misattribute on account-switched profiles) is now disclosed on all three affected artifacts;wireCookiesswitched from a hand-built read-only URI to the repo'sopen_sqlite_db_readonlyhelper; the Wire service-worker encryption note is applied only to rows with a resolved asset URL instead of unconditionally.Citations added (verified)
Discord Snowflake ID format, Microsoft DPAPI, Chromium page-transition types and History schema, AWS CloudFront signed-URL expiry. Two claims could not be sourced and were reworded rather than cited: Discord's per-message attachment cap (absent from the Message resource docs) and the Wire AVS call end-reason enum — both now state the limitation instead of implying authority.
Compiles clean; lint gate passes with zero new warnings; all 17 tests pass.
🤖 Generated with Claude Code