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