Pure-Kotlin classifier for feature/codebrowser/content/ that turns already-loaded SourceContent bytes into bounded text, binary, Git LFS pointer, unsupported-encoding, or oversized results with caller-supplied positive byte/character/line limits, per handoff/task-006a-ready. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
102 lines
12 KiB
Markdown
102 lines
12 KiB
Markdown
# UBGitea development log
|
|
|
|
This is the append-only implementation and handoff record shared by Codex and Claude. Only the current task owner or assigned reviewer may append an entry, and agents never edit this file concurrently.
|
|
|
|
## 2026-08-25 — TASK-001
|
|
|
|
- Agent and role: Codex, implementer and integrator
|
|
- Commit/diff: `75aa5f8`
|
|
- Features implemented: Android Compose project bootstrap, Korean placeholder home screen, deterministic Gradle wrapper, unit-test and lint baseline.
|
|
- How it was implemented: One application module using Kotlin, Compose, Material 3, API 28 minimum, API 36 target, JDK 17, and version-catalog-managed dependencies.
|
|
- Files changed: Root Gradle configuration, `app/`, ADR-001, product and task documentation.
|
|
- Checks and results: Debug APK build passed; 1 unit test passed; lint passed; sensitive-pattern scan found no assigned secret.
|
|
- Review findings and resolutions: Independent review found no P0-P3 findings.
|
|
- Known limitations: No device/emulator launch; final icon and authentication were out of scope.
|
|
- Next recommended task: Repository browsing foundations.
|
|
- Next owner: Codex.
|
|
|
|
## 2026-08-25 — TASK-003
|
|
|
|
- Agent and role: Codex, implementer and integrator
|
|
- Commit/diff: `a2cc7d4`
|
|
- Features implemented: Immutable repository, branch, tree, file, commit and paging domain contracts; safe coordinate/ref/path validation; read-only repository interface and browse use cases.
|
|
- How it was implemented: Pure Kotlin domain models, defensive byte/list copies, shared pagination validation, Korean read-only placeholder state, and fake-adapter unit tests.
|
|
- Files changed: Domain model/repository/use-case packages, focused tests, home placeholder, product roadmap and TASK-003 through TASK-007 documents.
|
|
- Checks and results: Build passed; 22 unit tests passed; lint passed; sensitive-pattern and diff checks passed.
|
|
- Review findings and resolutions: Two P2 findings covering page output mutability and missing use-case boundary tests were fixed and independently re-reviewed; no findings remain.
|
|
- Known limitations: Live HTTP, authentication, navigation, content rendering, and device testing were out of scope.
|
|
- Next recommended task: OAuth protocol core followed by Android OAuth integration.
|
|
- Next owner: Codex.
|
|
|
|
## 2026-08-25 — TASK-002A
|
|
|
|
- Agent and role: Codex, implementer and integrator
|
|
- Commit/diff: `6da016c`
|
|
- Features implemented: OAuth client configuration, approved read-only scopes, fresh PKCE S256 verifier/state generation, authorization URL construction, exact redirect validation, transaction expiry, denial/success modeling, and strict callback query validation.
|
|
- How it was implemented: Pure Kotlin/JDK code with `SecureRandom`, SHA-256, unpadded Base64 URL encoding, RFC 7636 verifier grammar, deterministic query component encoding, constant-time state comparison, strict UTF-8 percent decoding, duplicate/ambiguous response rejection, saturating time boundaries, and redacted string representations for sensitive values.
|
|
- Files changed: `core/auth/protocol/`, matching protocol tests, ADR-002, TASK-002 umbrella, TASK-002A, and TASK-002B.
|
|
- Checks and results: Focused OAuth tests 21/21 passed; full unit tests 43/43 passed; debug APK build passed; Android lint passed; diff check passed; sensitive-pattern scan found no assigned secret/token/password/private key.
|
|
- Review findings and resolutions: P2 verifier grammar fixed with strict RFC character/length validation; P2 parameter pollution and malformed UTF-8 fixed with fail-closed parsing; P3 timestamp overflow fixed with saturating boundaries. Independent re-review found no remaining P0-P3 findings.
|
|
- Known limitations: System browser launch, App Link dispatch, code exchange, Keystore token vault, user identity, and real-server E2E are intentionally deferred to TASK-002B. E2E remains blocked by signing fingerprints and hosted `assetlinks.json`.
|
|
- Next recommended task: TASK-002B Android OAuth integration, completing locally testable browser/storage/exchange boundaries before the external E2E gate.
|
|
- Next owner: Codex.
|
|
|
|
## 2026-08-25 — TASK-011
|
|
|
|
- Agent and role: Codex, implementer and integrator
|
|
- Commit/diff: current TASK-011 working-tree diff; user-owned `assetlinks.json` excluded
|
|
- Features implemented: System-browser Gitea OAuth login, verified HTTPS App Link callback, PKCE code exchange without a client secret, Keystore-backed token storage and logout, authenticated identity check, and a paginated list of every repository visible to the account.
|
|
- How it was implemented: Exact callback validation reuses TASK-002A; pending verifier/state is consumed once; OkHttp runs asynchronously with cancellation/error propagation; Gson DTOs fail closed into typed API errors; `/api/v1/user` precedes bounded/deduplicated `/api/v1/user/repos`; Compose exposes localized signed-out, browser-waiting/cancel, loading, content, empty, offline, permission, expired-auth, callback, and server-error states.
|
|
- Files changed: Android manifest and extraction rules, network/auth/repository data layers, repository ViewModel/Compose screen, dependencies/resources, focused tests, and TASK-002B/004/005/011 status documentation.
|
|
- Checks and results: Debug APK build passed; 57 unit tests across 16 suites passed; Android lint passed; diff and sensitive-pattern checks passed; no WebView or production client secret exists.
|
|
- Review findings and resolutions: Browser cancellation dead-end, HTTP response-read exception handling, signed-in error recovery/logout, nullable DTO validation, immutable UI snapshots, and bounded pagination coverage were fixed. Final independent re-review reported no remaining P0/P1.
|
|
- Known limitations: No Android device is connected, so the hosted App Link, system-browser return, live account login, repository result, and device Keystore behavior require one manual E2E run on the target phone.
|
|
- Next recommended task: Install the debug APK on the target Android device and verify login plus the internal repository list; after that, begin branch browsing.
|
|
- Next owner: Human product owner for device E2E, then Codex.
|
|
|
|
## 2026-08-25 — TASK-011 device E2E closure
|
|
|
|
- Agent and role: Human product owner, device verifier; Codex, evidence recorder
|
|
- Verification performed: Installed application login against the production company Gitea and retrieval of the authenticated account's internal repository list.
|
|
- Result: System-browser OAuth, verified App Link return, authenticated API access, and repository-list rendering passed on the target device.
|
|
- Review status: Automated gates previously passed and final independent review reported no P0/P1; the remaining manual device gate is now closed.
|
|
- Task status: TASK-011 complete.
|
|
- Next recommended task: Add repository selection and branch listing.
|
|
- Next owner: Codex.
|
|
|
|
## 2026-08-25 — TASK-012
|
|
|
|
- Agent and role: Codex, workflow implementer
|
|
- Commit/diff: TASK-012 documentation diff
|
|
- Features implemented: Durable current-state and remaining-roadmap handoff, Claude working-style prompt, and bidirectional append-only question/answer mailboxes.
|
|
- How it was implemented: Writer-specific directories and immutable per-message files preserve the single-writer protocol; the roadmap orders work by frozen-contract dependencies and assigns one owner per task.
|
|
- Files changed: `handoff/`, TASK-006A status, TASK-012, collaboration documentation, and this log.
|
|
- Checks and results: Documentation paths, baseline commits, ownership, task dependencies, and mailbox cross-references inspected; no Android code or external infrastructure changed.
|
|
- Review findings and resolutions: Pending Claude read-only review of the handoff package.
|
|
- Known limitations: Mailboxes coordinate repository-based handoff and do not provide real-time notification; agents must inspect them at task start.
|
|
- Next recommended task: Claude implements TASK-006A only and hands its commit to Codex for review.
|
|
- Next owner: Claude.
|
|
|
|
## 2026-08-25 — TASK-012 review closure and activation
|
|
|
|
- Agent and role: Codex, finding resolver and handoff owner; Claude, independent read-only reviewer
|
|
- Commit/diff: reviewed package commit `57d1c09`; immutable activation ref `handoff/task-006a-ready`
|
|
- Findings resolved: Canonical delivery sequence now explicitly permits independent TASK-006A before the TASK-004/005 remainder; TASK-006A authorizes only its completion-log append; both mailbox directions share symmetric immutable templates and unique correction filenames; completed OAuth evidence is synchronized.
|
|
- Checks and results: Documentation cross-references and task dependencies inspected; `git diff --check` passed before activation; no Android production file or external infrastructure changed.
|
|
- Review result: No handoff activation occurs until the tag resolves to the committed metadata state. Claude checks out the tag, creates a `claude/` branch, implements TASK-006A only, and then stops for Codex review.
|
|
- Known limitation: Repository mailboxes are asynchronous and must be checked manually at task start.
|
|
- Next owner: Claude for TASK-006A.
|
|
|
|
## 2026-08-25 — TASK-006A implementation
|
|
|
|
- Agent and role: Claude, assigned feature implementer (writable scope limited to `feature/codebrowser/content/` and this task's evidence/log entries)
|
|
- Commit/diff: branch `claude/task-006a-ready` created from activation tag `handoff/task-006a-ready` (base `965d55d`); implementation adds `ContentClassification.kt`, `SourceContentClassifier.kt`, and `SourceContentClassifierTest.kt` under `feature/codebrowser/content/`
|
|
- Features implemented: Pure-Kotlin classifier that turns already-loaded `SourceContent` bytes into one of five immutable states — bounded text (with independent line/character truncation flags), binary, Git LFS pointer, unsupported encoding, or oversized — using caller-supplied positive byte/character/line limits.
|
|
- How it was implemented: Oversized input is rejected by raw byte count before any decoding; binary is detected by a raw NUL-byte scan; text decoding uses a strict UTF-8 `CharsetDecoder` with `CodingErrorAction.REPORT` for malformed and unmappable input so it never substitutes replacement characters; a Git LFS pointer is recognized only from the exact canonical `version` line followed by valid `oid sha256:<64 hex>` and `size <integer>` lines within the 1024-byte spec bound; remaining text is truncated independently by line count and character count with an explicit `isTruncated` flag. No shared domain, data, Gradle, manifest, or navigation file was modified; `RepositoryModels.kt`/`RepositoryPath.kt`/`RepositoryRef.kt` remain identical to contract-freeze commit `0929282`.
|
|
- Files changed: `app/src/main/java/com/ubisam/ubgitea/feature/codebrowser/content/ContentClassification.kt`, `app/src/main/java/com/ubisam/ubgitea/feature/codebrowser/content/SourceContentClassifier.kt`, `app/src/test/java/com/ubisam/ubgitea/feature/codebrowser/content/SourceContentClassifierTest.kt`, `tasks/006a-code-content-classifier.md` (evidence/status), this log entry.
|
|
- Checks and results: `./gradlew testDebugUnitTest --tests "com.ubisam.ubgitea.feature.codebrowser.content.*"` passed (25/25); `./gradlew assembleDebug testDebugUnitTest lintDebug --rerun-tasks` passed (82 unit tests repository-wide, 0 failures; lint 0 errors, 22 pre-existing warnings unchanged from TASK-001 baseline); `git diff --check` clean; sensitive-pattern scan of changed files found no secret/token/password/private-key markers.
|
|
- Review findings and resolutions: None yet — pending Codex read-only review.
|
|
- Known limitations: No Android device/emulator was used, since this task has no Android framework dependency (pure JVM-testable Kotlin); static formatting/check task remains unconfigured for the module.
|
|
- Next recommended task: Codex reviews this commit read-only per `docs/workstreams.md` cross-review rules; TASK-006 UI remains blocked until Codex freezes the TASK-004/005 contracts.
|
|
- Next owner: Codex, for review.
|