# TASK-006A: Classify source content safely Status: ready — shared domain contract frozen at commit `0929282` Owner: Claude Reviewer: Codex ## Outcome Classify already-loaded repository content into bounded text, binary, Git LFS pointer, unsupported encoding, or oversized states so the future code viewer never blindly decodes or renders arbitrary bytes. ## Contract freeze - Shared domain contract commit: `0929282`. - Claude starts from the later Codex assignment commit that adds this task and prompt; no shared domain file may differ from `0929282` without an approved contract change. - Input contracts: `SourceContent`, `SourceFile`, `RepositoryPath`, and `RepositoryRef` from TASK-003. - This task must not change the frozen domain contracts. Required changes use the request format in `docs/workstreams.md`. ## Writable paths - `app/src/main/java/com/ubisam/ubgitea/feature/codebrowser/content/` - `app/src/test/java/com/ubisam/ubgitea/feature/codebrowser/content/` - `tasks/006a-code-content-classifier.md` evidence and review sections only ## Acceptance criteria - [ ] Classification results are immutable and distinguish text, binary, Git LFS pointer, unsupported encoding, and oversized content. - [ ] Maximum input bytes, rendered characters, and rendered lines are constructor-injected positive limits. - [ ] Oversized input is rejected before text decoding and exposes only safe metadata, not decoded content. - [ ] Binary detection includes NUL bytes and does not convert arbitrary bytes to replacement characters. - [ ] Text decoding uses a strict UTF-8 decoder that reports malformed or unmappable input. - [ ] A Git LFS pointer is recognized only from its canonical version line and required object ID/size fields within configured bounds. - [ ] Rendered text is explicitly marked truncated when character or line limits are exceeded. - [ ] No Android, network, persistence, token, logging, or write-operation dependency appears in the package. - [ ] Tests cover empty/ASCII/Korean text, CRLF, malformed UTF-8, NUL/binary, valid and malformed LFS pointers, exact/over byte limits, line limits, character limits, and defensive immutability. ## Security and privacy - Test fixtures must contain only synthetic public content. - Classification errors must not include source content in messages. - The classifier does not persist content or place it on the clipboard. ## Required checks ```text ./gradlew assembleDebug ./gradlew testDebugUnitTest ./gradlew lintDebug ./gradlew testDebugUnitTest --tests "com.ubisam.ubgitea.feature.codebrowser.content.*" ``` ## Handoff Claude must provide the exact branch/commit, changed paths, acceptance-criteria evidence, check results, open findings, and a request for Codex review. No integration or shared-file edit is authorized by this task. ## Evidence Pending Claude implementation.