chore: initialize UBGitea engineering harness

This commit is contained in:
최민영 2026-08-25 21:18:26 +09:00
commit dd9a70839c
12 changed files with 473 additions and 0 deletions

12
.gitignore vendored Normal file
View File

@ -0,0 +1,12 @@
.gradle/
.idea/
local.properties
**/build/
captures/
.externalNativeBuild/
.cxx/
*.jks
*.keystore
keystore.properties
secrets.properties
*.log

126
AGENTS.md Normal file
View File

@ -0,0 +1,126 @@
# UBGitea Engineering Contract
This file is the canonical instruction source for every coding agent. If another agent-specific file conflicts with this file, this file wins.
## Product
UBGitea is an Android client for the company Gitea instance.
- Gitea base URL: `https://gitea.ubisampaju.synology.me`
- OAuth client ID: `225589df-b992-4676-aae0-b2534ba7452d`
- OAuth redirect URI: `https://gitea.ubisampaju.synology.me/ubisampaju/oauth/callback`
- Authentication: OAuth 2.0 Authorization Code with PKCE (`S256`)
- Client secret: never required, requested, stored, logged, or committed
Treat the base URL and client ID as configuration, even while they have production defaults.
## Source of truth
Before work, read in this order:
1. `AGENTS.md`
2. The assigned file under `tasks/`
3. Relevant documents under `docs/`
4. Existing code and tests
Do not implement a feature without an acceptance-criteria task file. If requirements conflict or a security-sensitive choice is missing, stop and record the question rather than inventing behavior.
## Agent roles
### Codex — implementer and integrator
- Owns repository edits unless the task explicitly transfers ownership.
- Inspects existing code before changing it.
- Implements the smallest coherent change satisfying the task.
- Runs required checks and records evidence.
- Resolves review findings and keeps documentation synchronized.
### Claude — independent reviewer and design critic
- Starts read-only unless explicitly assigned implementation ownership.
- Reviews requirements, architecture, security, UX, tests, and the current diff.
- Does not rewrite code while reviewing.
- Reports findings with severity, evidence, reproduction, and acceptance condition.
- May implement only after receiving a task that names its writable file scope.
### Human product owner
- Decides product behavior, branding, external infrastructure, and release approval.
- Approves destructive operations and any change to OAuth or production configuration.
## Single-writer protocol
- Only one agent may write a file during a task.
- Codex and Claude must not edit the same working tree concurrently.
- A handoff must identify task ID, current commit or diff, writable paths, completed checks, open findings, and next action.
- Never accept a review based only on “looks good.” Use acceptance criteria and test evidence.
## Required work cycle
1. Restate the task outcome and risks.
2. Inspect relevant files and current git status.
3. Plan a small change with explicit file ownership.
4. Implement.
5. Run the checks listed in the task.
6. Review the diff against acceptance criteria.
7. Ask the independent reviewer to inspect it.
8. Resolve findings and rerun checks.
9. Update task evidence and hand off.
## Android engineering rules
- Kotlin and Jetpack Compose are the default UI stack.
- Prefer unidirectional data flow and immutable UI state.
- Keep Android framework details at the edges of domain and data logic.
- Use coroutines with structured concurrency; do not use global scopes.
- Keep network DTOs separate from domain models.
- Never perform network or disk work on the main thread.
- All user-visible text belongs in string resources.
- Accessibility labels, loading, empty, offline, and error states are required.
- Avoid new dependencies unless the task explains why the standard stack is insufficient.
## Security invariants
- Use the system browser for OAuth; do not use WebView for credential entry.
- Generate a fresh PKCE verifier, S256 challenge, and cryptographically random `state` per login attempt.
- Reject missing or mismatched `state` and unexpected redirect URIs.
- Never log authorization codes, access tokens, refresh tokens, cookies, or personal data.
- Store tokens using Android Keystore-backed protection.
- Do not disable TLS validation or add trust-all certificates.
- Do not place secrets in source, resources, Gradle properties, screenshots, fixtures, or CI logs.
- Destructive Gitea operations require explicit UI confirmation and dedicated task approval.
## Verification gates
Before a task is complete, run all applicable checks:
- Gradle build
- Unit tests
- Android lint
- Static formatting/check task when configured
- Focused tests for changed behavior
- Secret scan or repository search for sensitive values
- Manual verification steps named by the task
If a check cannot run, record the exact reason and do not claim the task is complete.
## Review severity
- `P0`: credential exposure, data loss, remote compromise, or release blocker
- `P1`: broken primary flow, authorization flaw, crash, or serious regression
- `P2`: incorrect edge case, maintainability problem, missing important test
- `P3`: minor quality or consistency improvement
Each finding must include file and line, concrete impact, evidence, and the condition that closes it.
## Git discipline
- Preserve unrelated user changes.
- Keep commits focused on one task.
- Do not rewrite history, force-push, delete branches, or discard changes without approval.
- Do not commit generated build output, local SDK paths, signing keys, tokens, or secrets.
- Branch names should use `codex/` for Codex-owned work and `claude/` for Claude-owned work.
## Definition of done
A task is done only when its acceptance criteria are met, required checks pass, no unresolved P0/P1 findings remain, documentation reflects material decisions, and a reviewer can reproduce the result from the recorded evidence.

7
CLAUDE.md Normal file
View File

@ -0,0 +1,7 @@
# Claude entry point
Read `AGENTS.md` first. It is the canonical instruction source.
Your default role in this repository is independent reviewer and design critic. Stay read-only unless the human product owner or an assigned task explicitly grants you implementation ownership and lists writable paths.
For a review, use `prompts/claude-review.md` and report findings before summaries. Never request or expose the OAuth client secret.

15
README.md Normal file
View File

@ -0,0 +1,15 @@
# UBGitea
Android client for the Ubisam Paju Gitea instance.
The repository currently contains the engineering harness that governs collaborative development by Codex and Claude. Product code will be bootstrapped through the tasks under `tasks/`.
## Start here
1. Read `AGENTS.md`.
2. Read `docs/product.md` and `docs/architecture.md`.
3. Select one task from `tasks/`.
4. Assign one writer and one independent reviewer.
5. Record build and test evidence before marking the task complete.
OAuth uses Authorization Code with PKCE and does not use a client secret.

48
docs/architecture.md Normal file
View File

@ -0,0 +1,48 @@
# Architecture guardrails
## Proposed stack
- Kotlin
- Jetpack Compose and Material 3
- Coroutines and Flow
- Hilt for dependency injection
- Retrofit/OkHttp or Ktor Client, selected once in an ADR
- Room only when offline caching is approved
- AndroidX Browser/AppAuth-compatible system-browser OAuth flow
## Layers
```text
UI (Compose)
-> presentation state and events
-> domain use cases and models
-> repository interfaces
-> data implementations
-> Gitea HTTP API / secure local storage
```
Dependencies point inward. DTOs, HTTP clients, Android contexts, and persistence entities do not leak into domain models.
## Initial module strategy
Begin with one application module and package by feature. Split Gradle modules only when build time or ownership boundaries justify the added complexity.
```text
app/
core/auth
core/network
core/designsystem
feature/login
feature/repositories
feature/issues
feature/pullrequests
feature/notifications
```
## Configuration
Production defaults may contain the public Gitea URL and OAuth client ID. Environment-specific values must be injectable for tests. Client secrets and signing material must never be committed.
## Architecture decisions
Material choices belong in `docs/decisions/` as short ADRs stating context, decision, alternatives, and consequences.

31
docs/collaboration.md Normal file
View File

@ -0,0 +1,31 @@
# Codex and Claude collaboration
## Operating model
One agent writes; the other reviews. Roles can rotate between tasks, but ownership cannot be ambiguous within a task.
## Handoff format
```markdown
Task: TASK-###
Role completed: implementer | reviewer
Commit/diff: <identifier>
Writable scope used: <paths>
Acceptance criteria status: <list>
Checks run: <commands and outcomes>
Open findings: <P0-P3 list>
Known limitations: <list>
Next owner/action: <one concrete action>
```
## Conflict handling
1. Product requirements and human decisions win.
2. `AGENTS.md` wins over agent-specific files.
3. Task acceptance criteria win over implementation preference.
4. Automated evidence wins over an unsupported assertion.
5. Security-sensitive ambiguity is escalated to the human owner.
## Review independence
The reviewer must inspect the actual diff and tests. Do not provide the implementer's reasoning as a substitute for evidence; it can anchor the reviewer and hide alternative failure modes.

35
docs/oauth.md Normal file
View File

@ -0,0 +1,35 @@
# OAuth and App Link contract
## Registered values
```text
Authorization endpoint: https://gitea.ubisampaju.synology.me/login/oauth/authorize
Token endpoint: https://gitea.ubisampaju.synology.me/login/oauth/access_token
Client ID: 225589df-b992-4676-aae0-b2534ba7452d
Redirect URI: https://gitea.ubisampaju.synology.me/ubisampaju/oauth/callback
Grant: Authorization Code with PKCE
PKCE method: S256
Client secret: not used
```
## Required login flow
1. Create a random state and PKCE verifier.
2. Derive the S256 challenge.
3. Store only the minimum short-lived transaction state.
4. Open the authorization URL in the system browser.
5. Receive the verified HTTPS App Link.
6. Validate scheme, host, path, state, error, and authorization code.
7. Exchange the code using the original verifier.
8. Store tokens with Keystore-backed protection.
9. Clear transaction state on success, cancellation, or error.
## External prerequisite
The host must serve a valid Android Digital Asset Links file at:
```text
https://gitea.ubisampaju.synology.me/.well-known/assetlinks.json
```
It must identify the final Android application ID and signing-certificate SHA-256 fingerprint. OAuth end-to-end testing is blocked until those values and hosting are available.

39
docs/product.md Normal file
View File

@ -0,0 +1,39 @@
# Product brief
## Purpose
UBGitea gives employees a focused Android experience for the company Gitea instance without attempting to reproduce every web feature.
## MVP outcomes
1. Sign in through Gitea OAuth 2.0 with PKCE.
2. View the signed-in user and organizations.
3. Browse accessible repositories, branches, directories, and files.
4. View issues, pull requests, and notifications.
5. Sign out and remove locally stored credentials.
The first release is read-oriented. Creating, merging, deleting, or administering resources is out of scope until explicitly approved.
## UX principles
- Korean-first copy with a structure that permits localization.
- Clear loading, empty, offline, authentication-expired, and server-error states.
- Never obscure which Gitea instance and account are active.
- Require confirmation before any future destructive or irreversible operation.
## Non-goals for MVP
- Editing source files
- Git clone/push over SSH
- Repository or account administration
- Gitea Actions runner administration
- Package publishing
- Multiple Gitea instances
## Open product decisions
- Final Android application ID
- Minimum supported Android version
- Visual identity, icon, and color palette
- Whether biometric reauthentication is required
- Whether repositories must be cached for offline browsing

44
prompts/claude-review.md Normal file
View File

@ -0,0 +1,44 @@
# Claude kickoff prompt for UBGitea
You are the independent reviewer and design critic for the UBGitea Android repository.
Before doing anything, read these files completely in order:
1. `AGENTS.md`
2. `CLAUDE.md`
3. `docs/product.md`
4. `docs/architecture.md`
5. `docs/oauth.md`
6. `docs/collaboration.md`
7. The assigned task under `tasks/`
Your default mode is read-only. Do not edit files, install dependencies, change external services, or reveal secrets unless the human product owner explicitly changes your role and provides writable paths.
For the current task:
1. Inspect the repository, git status, assigned task, actual diff, and relevant tests.
2. Verify every acceptance criterion with concrete evidence.
3. Independently examine architecture, Android lifecycle behavior, concurrency, accessibility, Gitea API correctness, OAuth 2.0 PKCE, App Link validation, token handling, privacy, and missing tests.
4. Do not accept claims that are unsupported by code or executable checks.
5. Report findings first, ordered by `P0` through `P3`.
6. For each finding include: severity, concise title, exact file and line, impact, evidence or reproduction, and the condition that closes it.
7. If there are no actionable findings, say so explicitly and list residual risks or checks you could not run.
8. Finish with a short handoff using the format in `docs/collaboration.md`.
Security invariants:
- Never ask for, store, print, or commit the OAuth client secret.
- UBGitea is a public OAuth client using Authorization Code with PKCE S256.
- Login credentials must be entered only in the system browser.
- Reject mismatched state, unexpected callback host/path, and invalid authorization responses.
- Never disable TLS verification or log authorization codes and tokens.
Current fixed public configuration:
```text
Gitea URL: https://gitea.ubisampaju.synology.me
OAuth client ID: 225589df-b992-4676-aae0-b2534ba7452d
Redirect URI: https://gitea.ubisampaju.synology.me/ubisampaju/oauth/callback
```
Begin by stating which task and commit/diff you are reviewing and whether any required context is missing. Then perform the review without modifying the repository.

42
tasks/001-bootstrap.md Normal file
View File

@ -0,0 +1,42 @@
# TASK-001: Bootstrap the Android project
Status: ready
Owner: Codex
Reviewer: Claude
## Outcome
Create an Android Studio project that builds a minimal UBGitea Compose application and establishes deterministic local checks.
## Scope
- Included: Gradle wrapper, one Android application module, Compose theme, placeholder home screen, unit-test baseline, lint, CI-ready commands.
- Excluded: OAuth implementation, Gitea API calls, final branding assets.
## Writable paths
- Root build and configuration files
- `app/`
- `.github/` if CI is selected
- Documentation updates needed to record chosen versions
## Acceptance criteria
- [ ] Android Studio can import the project without manual source edits.
- [ ] Debug APK builds successfully.
- [ ] Unit tests and Android lint run successfully.
- [ ] The launcher displays `UBGitea` and a placeholder state.
- [ ] No secret or client secret is present.
- [ ] Final application ID and minimum SDK are recorded in an ADR.
## Required checks
```text
./gradlew assembleDebug
./gradlew testDebugUnitTest
./gradlew lintDebug
```
## Evidence
Pending implementation.

32
tasks/002-oauth-spike.md Normal file
View File

@ -0,0 +1,32 @@
# TASK-002: Prove OAuth PKCE and App Link end to end
Status: blocked by TASK-001 and external App Link configuration
Owner: Codex
Reviewer: Claude
## Outcome
A user can authorize UBGitea through the system browser, return through the verified App Link, exchange the code using PKCE, and view their Gitea identity.
## Acceptance criteria
- [ ] Uses a system browser, not WebView.
- [ ] Uses fresh random state and PKCE S256 per attempt.
- [ ] Rejects mismatched state and malformed callbacks.
- [ ] Does not require or contain a client secret.
- [ ] Does not log codes or tokens.
- [ ] Persists tokens with Keystore-backed protection.
- [ ] Handles success, cancellation, denied authorization, network failure, and expired transaction state.
- [ ] Calls the authenticated user endpoint and displays the user identity.
- [ ] Tests cover URL construction, PKCE, callback validation, and error mapping.
## External prerequisites
- Final application ID
- Debug and release signing certificate fingerprints
- Correct `assetlinks.json` hosted on the Gitea domain
- OAuth application configured as a public client
## Evidence
Pending prerequisites and implementation.

42
tasks/TEMPLATE.md Normal file
View File

@ -0,0 +1,42 @@
# TASK-###: Title
Status: proposed
Owner: unassigned
Reviewer: unassigned
## Outcome
Describe observable user or engineering outcome.
## Scope
- Included:
- Excluded:
## Writable paths
- `path/`
## Acceptance criteria
- [ ] Observable criterion
- [ ] Error/edge-case criterion
- [ ] Test criterion
## Security and privacy
List relevant invariants or write `No additional concerns`.
## Required checks
```text
Exact commands are added once the build exists.
```
## Evidence
Record command output summaries, screenshots, and manual verification without secrets.
## Review findings
Track finding ID, severity, disposition, and closing evidence.