chore: initialize UBGitea engineering harness
This commit is contained in:
commit
dd9a70839c
12
.gitignore
vendored
Normal file
12
.gitignore
vendored
Normal 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
126
AGENTS.md
Normal 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
7
CLAUDE.md
Normal 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
15
README.md
Normal 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
48
docs/architecture.md
Normal 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
31
docs/collaboration.md
Normal 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
35
docs/oauth.md
Normal 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
39
docs/product.md
Normal 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
44
prompts/claude-review.md
Normal 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
42
tasks/001-bootstrap.md
Normal 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
32
tasks/002-oauth-spike.md
Normal 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
42
tasks/TEMPLATE.md
Normal 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.
|
||||
Loading…
x
Reference in New Issue
Block a user