# TASK-003: Establish repository browsing foundations Status: complete Owner: Codex Reviewer: Claude ## Outcome Define the immutable domain contracts and presentation states needed to browse repositories, branches, directory entries, and source files without coupling the UI to Gitea DTOs or Android framework types. ## Scope - Included: domain models, repository interface, validated repository location/ref/path value objects, browse use cases, immutable screen state, focused unit tests, and a placeholder home state that describes the read-only experience. - Excluded: live HTTP calls, OAuth tokens, persistence, syntax highlighting, navigation between final screens, and write operations. ## Writable paths - `app/src/main/java/com/ubisam/ubgitea/domain/` - `app/src/main/java/com/ubisam/ubgitea/ui/home/` - `app/src/main/res/values/strings.xml` - `app/src/test/java/com/ubisam/ubgitea/` - Documentation and task evidence required for this task ## Acceptance criteria - [x] Repository, branch, tree-entry, source-file, and commit-summary models are immutable, defensively copy mutable input, and contain no network or Android types. - [x] Repository coordinates reject blank owner/name values. - [x] Refs reject blank values and control characters while permitting normal Gitea branch, tag, and commit names. - [x] Repository paths normalize a leading slash, reject traversal segments and control characters, and preserve valid nested paths. - [x] The repository interface is read-only and exposes paged repositories plus branch, tree, file, and commit queries. - [x] Home UI uses an explicit immutable state and shows a Korean read-only placeholder using string resources. - [x] Unit tests cover valid and invalid coordinates, refs, paths, defensive content copying, and paged-list copying. - [x] No secret, token, network DTO, or Android framework dependency appears in the domain package. ## Required checks ```text ./gradlew assembleDebug ./gradlew testDebugUnitTest ./gradlew lintDebug ``` ## Evidence Recorded on 2026-08-25 using JDK 17 and Android SDK 36: - `./gradlew assembleDebug` — passed. - `./gradlew testDebugUnitTest` — passed; 22 tests across 6 suites, 0 failures, 0 errors. - Focused domain/use-case tests — passed; page output mutation is rejected, all paged use cases share the same bounds, and invalid input does not reach the repository adapter. - `./gradlew lintDebug` — passed. - Sensitive-pattern repository scan excluding generated and Git metadata — no assigned secret, token, password, or private-key value found. - `git diff --check` — passed. - Actual device/emulator interaction was not required because this task establishes domain contracts and a placeholder state only. - Independent read-only implementation review — initial P2 findings for page output mutability and incomplete use-case boundary tests were fixed; re-review found no remaining P0-P3 findings. - Reviewer independently reran `assembleDebug`, `testDebugUnitTest`, and `lintDebug` successfully after the fixes.