Repository navigation
3.0.0
Twitter Hide Ads v3.0.0
A hand-written Brainfuck policy core, compiled ahead of time
This release moves every filtering decision into Brainfuck, without changing what the module removes.
Changed
- The filtering and decision policy is now three hand-written Brainfuck programs in
libtwitterbf.so(brainfuck/src/post.bf,action.bf,discovery.bf), compiled ahead of time to C and then to native code with the NDK. There is no interpreter in the APK.post: the entry-identifier grammar (segment boundaries, nestedconversationthread-…andsearch-conversation-…prefixes, the 256-character limit), the "mentions promoted" ambiguity rule, verdict precedence, Video Tab item classes, the safe-mixed-batch rule and the copy and verification checks.action: whether a value found by the fallback walk names a promoted post action.discovery: render and Video Tab boundary eligibility, scores and thresholds, the exact-profile version table, and the discovery and traversal limits.
- Hooks, DexKit discovery, reflection, caching and Kotlin list rebuilding stay in Java. Each render makes one
@FastNativecall with the post's text fields and a metadata flag, and allocates nothing. - Faster on a Pixel 8 Pro (release build): an organic post is classified in 2.4 µs (was 14.9 µs), a promoted post in 1.1 µs (was 6.1 µs), a 20-item Video Tab batch in 6.8 µs (was 275 µs).
- Fails open on any policy failure: a missing library or ABI mismatch installs no hook, and an oversized, malformed or budget-exhausted request keeps the content.
- New adaptive vector launcher icon — a struck-through shield over the X mark — with a themed (monochrome) layer.
- Per-render boundary observation logs are debug-only; block logs now carry policy counters.
- CI is split into test, build and release jobs. Signing secrets exist only in the release job, and the build checks that every native library ships in the APK.
- The README follows the ThreadsHideAds layout; the design is documented in
docs/BRAINFUCK_ARCHITECTURE.mdand each program has a normative specification indocs/policy/.
Also in this release
- Timeline models are classified
PROMOTED,ORGANICorUNKNOWN. A confident organic entry identifier skips the reflective action-graph walk, and the walk's result is cached per model instance. - Entry identifiers must match the whole-value grammar, so
not-promoted-x,unpromoted-1or free text containingpromoted-never count. - Adaptive boundaries are witnessed at runtime and unhooked after 12 invocations without a post-like model.
- The
DexFilefallback coverscom.x.urt,com.x.jetfuelandcom.x.mappers, post package first. - Video Tab replacements are built through the persistent list's own builder; the dynamic-proxy emulation is removed.
- Release-build logs redact entry identifiers, and the unique-block key set is bounded to 512 entries.
Verified
- Parity with the 2.1.0 Java policy, kept as a frozen test oracle: 411 162 old-versus-new comparisons per run on the JVM and on arm64, including every character from U+0000 to U+FFFF, plus randomized, malformed-frame, concurrency and "organic is never blocked" tests.
- On a Pixel 8 Pro, Android 17, Vector 2.2, X 12.28.0-prod.01: a cold DexKit rescan scored by the Brainfuck policy selected the same 9 boundaries with the same scores as 2.1.0; promoted posts blocked before render on the Home timeline and in post detail (
conversationthread-<id>-promoted-tweet-<id>-<hash>); organic posts and replies untouched; search functional; Video Tab batches of 13, 24 and 35 entries filtered to 11, 22 and 31 with paging intact; no policy failures, crashes or ANRs.
No promoted search entry was served during the session. LSPatch, 32-bit and x86 devices were not run for this release.
Version metadata
- Version name:
3.0.0 - Android version code:
34 - Git tag:
v3.0.0 - APK filename:
TwitterHideAds-v3.0.0.apk
Updating
Install the v3.0.0 APK over v2.1.0, keep X (com.twitter.android) as the module's only scope, then force-stop and reopen X once. Confirm the framework log reports policyCore=brainfuck-aot abi=1.0 followed by enforcement=ACTIVE_ADAPTIVE.