summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-11-02 10:17:23 +0100
committerDanilo M. <danix@danix.xyz>2026-11-02 10:17:23 +0100
commit55f24b771fc2fb2be70f2d3a79c68cede28897fe (patch)
tree37c96c0291f5aa3885d3ba87939672b474ff481c
parentbea3e5020a9d5044df02aea4bae91359c864e4fe (diff)
downloadHardenedPass-55f24b771fc2fb2be70f2d3a79c68cede28897fe.tar.gz
HardenedPass-55f24b771fc2fb2be70f2d3a79c68cede28897fe.zip
docs: add AGENTS.md and CLAUDE.md
AGENTS.md holds the agent guidance for the fork: layout and remotes, build and test commands matching CI, verified gotchas, the manual public suffix list update with its last-run date, and the release signing status. CLAUDE.md only points at it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
-rw-r--r--AGENTS.md92
-rw-r--r--CLAUDE.md6
2 files changed, 98 insertions, 0 deletions
diff --git a/AGENTS.md b/AGENTS.md
new file mode 100644
index 00000000..a94a484d
--- /dev/null
+++ b/AGENTS.md
@@ -0,0 +1,92 @@
+# AGENTS.md
+
+Guidance for AI coding agents (Claude Code, opencode, etc) working in this repository.
+
+## What this is
+
+Maintained fork of Android Password Store, an Android client for `pass`
+(OpenPGP-encrypted files in a git repository). Upstream
+(`android-password-store/Android-Password-Store`) was archived in October 2024; the fork
+started in November 2026 from upstream's last commit. Kotlin, Gradle, about 18k lines.
+
+Modules: `app` (UI, git sync, autofill service), `autofill-parser`, `crypto:common`,
+`crypto:pgpainless`, `format:common`, `passgen:diceware`, `passgen:random`, `ui:compose`,
+`coroutine-utils`, `sentry-stub`. Build conventions live in `build-logic/`.
+
+The app name and `applicationId` (`app.passwordstore`) are still upstream's on purpose. Do not
+rename them unless asked: it is tied to the release-signing decision (see Releases).
+
+## Repository layout and remotes
+
+- `master` is the only branch. Upstream's `develop` was renamed; do not recreate it.
+- `origin` fetches from the maintainer's own git server (the main repository) and pushes to it
+ and to the GitHub fork (`danixland/Android-Password-Store`) in one `git push`.
+ GitHub is a push mirror: never create commits on GitHub (bots, web edits), they would
+ diverge from the main repository.
+- `upstream` is fetch-only (push URL disabled).
+- Work directly on `master`, no PRs.
+
+## Build and test
+
+Needs JDK 17 and the Android SDK. `local.properties` (gitignored) holds `sdk.dir`.
+
+ ./gradlew assembleFreeDebug # debug APK
+ ./gradlew test -PslimTests # unit tests, as CI runs them
+ ./gradlew spotlessApply # formatting (ktfmt); CI runs spotlessCheck
+ ./gradlew lintFreeRelease
+
+Prefix with `CI=1` to match CI: it turns Kotlin warnings into errors, so a deprecation warning
+that passes locally fails CI. Before committing, run:
+
+ CI=1 ./gradlew spotlessCheck test -PslimTests assembleFreeDebug assembleFreeRelease lintFreeRelease
+
+Flavors: `free` (no proprietary dependencies, Sentry replaced by `sentry-stub`) and `nonFree`
+(adds Sentry and Play Services SMS OTP).
+
+CI is `.github/workflows/pull_request.yml` (named "CI"), on push to `master`. Workflows use the
+`setup-gradle` composite action from this fork at `@master`. It checks the repository out
+itself, so it cannot be referenced with a local `./` path.
+
+## Verified facts and gotchas
+
+- Bouncy Castle: every `org.bouncycastle` module is forced to the catalog version by a
+ resolution rule in the root `build.gradle.kts`. PGPainless and sshj pull different versions,
+ and mixing them is unsupported.
+- Bouncy Castle and PGPainless 1.7.8 decrypt GnuPG's OCB (LibrePGP AEAD) packets, the default
+ since GnuPG 2.3. Older stacks rejected them as "non-standard AEAD"; that error path was
+ removed. `crypto/pgpainless/src/test/resources/gnupg_ocb_*` are real GnuPG 2.5 fixtures.
+- Test secret-key fixtures trip the maintainer's gitleaks pre-commit hook. A throwaway test key
+ is allowlisted by fingerprint in `.gitleaksignore`
+ (`<path>:private-key:<line>`). Never allowlist anything but generated test keys.
+- `app/lint-baseline.xml` entries for library jars are keyed on the jar's cache path, version
+ and hash included. A dependency bump that moves a baselined jar needs the path updated.
+- `LaunchActivity` is exported and forwards `FILE_PATH` to `DecryptActivity` (not exported)
+ only after `isFileInRepo` checks it canonically resolves inside the store.
+- JGit is pinned at 4.5.7 (2019). Newer JGit needs Java 11 APIs Android only partly desugars;
+ upgrading it is a large, separate job.
+
+## Maintenance tasks
+
+Recurring jobs with no automation. When starting a session, check the "last run" dates; if a
+task is overdue, remind the maintainer before other work. After running one, update its date
+here in the same commit.
+
+### Public suffix list (monthly, and before every release)
+
+Autofill uses Mozilla's Public Suffix List (`autofill-parser/src/main/assets/publicsuffixes`)
+to tell where a domain's registrable part starts. It was a weekly bot PR upstream; here it is
+manual because bot commits on the GitHub mirror would diverge from the main repository.
+
+ ./gradlew updatePSL
+ git diff --stat # no change: just update the date below
+ ./gradlew :autofill-parser:test -PslimTests
+ git commit -am "autofill-parser: update public suffix list" && git push
+
+Last run: 2026-11-02.
+
+## Releases
+
+Not set up yet. Upstream's encrypted signing keystore was removed (only upstream could decrypt
+it). `deploy_github_releases.yml` needs a keystore of our own, encrypted with
+`scripts/encrypt-secret.sh` into `secrets/`, and the `ENCRYPT_KEY` secret. A different signing
+key means the APK cannot update over upstream's install while `applicationId` is unchanged.
diff --git a/CLAUDE.md b/CLAUDE.md
new file mode 100644
index 00000000..0d863394
--- /dev/null
+++ b/CLAUDE.md
@@ -0,0 +1,6 @@
+# CLAUDE.md
+
+This file is intentionally thin. AGENTS.md is the single source of truth for
+project guidance, shared across every agent tool. Edit AGENTS.md instead.
+
+@AGENTS.md