Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 8 additions & 11 deletions .claude/commands/e2e-fold-loop.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@

> **Status: GOAL MET 2026-06-04** (branch `feature/e2e-fold-loop-fixes`). Iteration 1 found and
> fixed BUG-1 (pass-1 jitter subsampling → 15 fps + corrupted reverse half, commit `731b26b`);
> iteration 2 confirmed a zero-change clean sweep on all three devices. Reports + state:
> `docs/e2e/fold-loop/`. BUG-2 (skip-at-input corruption for >30 fps sources) remains open —
> see STATE.md. Re-run this loop after any media-pipeline change, or whenever a Pixel-family
> regression is suspected.
> iteration 2 confirmed a zero-change clean sweep on all three devices. Historical reports were
> archived during doc cleanup. BUG-2 (skip-at-input corruption for >30 fps sources) may still apply —
> re-run this loop after any media-pipeline change, or whenever a Pixel-family regression is suspected.

## THE GOAL

Expand Down Expand Up @@ -33,16 +32,14 @@ needed a mid-run fix doesn't count; the next iteration must confirm).

## Session bootstrap (context does not persist between sessions)

1. Read `CLAUDE.md` + every numbered lesson in `docs/lessons_learned/` (013, 018–023 are the
media-pipeline ones you'll need).
2. Read `docs/e2e/fold-loop/STATE.md` — iteration number, open bugs with fix-attempt counts,
what to do first. Missing = iteration 1: create it (template at bottom).
3. Read `.claude/skills/run-e2e-pixel-sweep/SKILL.md` in full — **it IS the mechanics** (the
1. Read `CLAUDE.md` + skim `docs/PRD-mission-control.md` media-pipeline sections and
`docs/guides/oem-regression-testing.md` (media-pipeline / codec lanes).
2. Read `.claude/skills/run-e2e-pixel-sweep/SKILL.md` — **it IS the mechanics** (the
scripted prep/drive/gate phases, validated 2026-06-04). Its parent `run-e2e` skill supplies
`scan-logcat.ps1` + the signature catalog and the honesty rules; both apply verbatim.
4. Git: branch `feature/e2e-fold-loop-fixes` (create from `main` if absent). Never commit to
3. Git: branch `feature/e2e-fold-loop-fixes` (create from `main` if absent). Never commit to
`main`. Never commit the video (gitignored).
5. **Do not trust training data.** Before any claim about Android API behavior or any fix
4. **Do not trust training data.** Before any claim about Android API behavior or any fix
design, WebSearch `developer.android.com` scoped to the repo's actual versions (re-read the
table in `CLAUDE.md` / `gradle/libs.versions.toml` — currently targetSdk 36, Kotlin 2.3.21,
Media3 1.10.1, CameraX 1.6.1). Pure-math fixes verified by device evidence in front of you
Expand Down
7 changes: 3 additions & 4 deletions .claude/skills/crashlytics-triage/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,8 @@ Official workflow: [Crashlytics AI assistance MCP](https://firebase.google.com/d
| Android **appId** (required on every MCP call) | `1:95815153197:android:c30254bb713d1e6ae96aa4` |
| Package / applicationId | `io.github.stozo04.openloop` |
| `google-services.json` | `app/google-services.json` (gitignored; plugins apply only when present) |
| Non-fatal reverse failures | `ReverseCrashlytics` — keys like `reverse_outcome`, `video_mime` |
| Product doc | `docs/diagnostics/firebase-crashlytics-trimming.md` |
| Issue `3a506c4e` verification | `docs/diagnostics/crashlytics-issue-3a506c4e-verification.md` |
| Non-fatal reverse failures | `ReverseCrashlytics.kt` — keys like `reverse_outcome`, `video_mime` |
| Codec churn / issue `3a506c4e` | [`docs/lessons_learned/020-*.md`](../../../docs/lessons_learned/020-imported-clips-hdr-codec-and-reverse-failure-recovery.md), [`023-*.md`](../../../docs/lessons_learned/023-media-pipeline-stages-must-count-output-samples.md), [`reverse-video-research.md`](../../../docs/guides/reverse-video-research.md) |

Non-fatals upload on **next app launch**, not instantly.

Expand Down Expand Up @@ -99,7 +98,7 @@ When the user gives an issue id, console URL, or picks one from Mode A:
3. `crashlytics_batch_get_events` using `sampleEvent` from the issue response; more samples via `crashlytics_list_events` with the same filters (`issueId`, versions, error types).
4. `crashlytics_list_notes` — resume prior on-call context.
5. Read stack frames in the repo (`VideoReverser`, `OpenLoopViewModel`, `ReverseCrashlytics`, etc.).
6. Cross-check `docs/active/` and `docs/diagnostics/` for known incidents (e.g. editor OOM `ef2823cf…`, trimming doc).
6. Cross-check [`docs/lessons_learned/020-imported-clips-hdr-codec-and-reverse-failure-recovery.md`](../../../docs/lessons_learned/020-imported-clips-hdr-codec-and-reverse-failure-recovery.md), [`023-media-pipeline-stages-must-count-output-samples.md`](../../../docs/lessons_learned/023-media-pipeline-stages-must-count-output-samples.md), and [`docs/guides/reverse-video-research.md`](../../../docs/guides/reverse-video-research.md) for known reverse/codec incidents.
7. Produce the investigation plan (do not implement until user confirms):

```markdown
Expand Down
4 changes: 2 additions & 2 deletions .claude/skills/run-e2e-pixel-sweep/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ Loopify save with `InvalidForegroundServiceTypeException: Starting FGS with type
(Crashlytics 9663c743, Galaxy A55). The fix gates to `dataSync` on API 29–34. After the three
API-35+ emulators pass, this device is the **mandatory FGS regression gate**: a green save +
`Worker result SUCCESS` for `BoomerangRenderWorker` and **zero** `InvalidForegroundServiceTypeException`
lines in logcat. See `docs/e2e/2026-06-22_082330-api34-fgs-fix.md` for the first verified run.
lines in logcat. See [`docs/guides/oem-regression-testing.md`](../../../docs/guides/oem-regression-testing.md) lane 1 (API 34 FGS).

```powershell
$avd = "Pixel_6" # then Pixel_8, then Pixel_10_Pro_Fold, then Pixel_8_API34
Expand Down Expand Up @@ -102,7 +102,7 @@ and block `setprop`; the emulator still reports `Google` / goldfish codecs.

### Samsung RTL sweep (real Galaxy hardware)

Setup: [`docs/guides/samsung-rtl-steps.md`](../../docs/guides/samsung-rtl-steps.md) — reserve device,
Setup: [`docs/guides/samsung-rtl-steps.md`](../../../docs/guides/samsung-rtl-steps.md) — reserve device,
start RDB, verify `adb devices` shows `localhost:<port>`.

```powershell
Expand Down
7 changes: 4 additions & 3 deletions .claude/skills/run-e2e/references/logcat-signatures.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ What `scan-logcat.ps1` greps for, what each means, and how to treat it. Classes:
## CHURN — advisory (resource-pressure smell)

These rarely fail a run on their own, but a cluster of them around a reverse that stalled is the
fingerprint of the editor-codec-churn disease (`docs/active/editor-codec-churn/IMPLEMENTATION.md`).
fingerprint of the editor-codec-churn disease (see [`docs/lessons_learned/023-media-pipeline-stages-must-count-output-samples.md`](../../../../docs/lessons_learned/023-media-pipeline-stages-must-count-output-samples.md)).

| Signature | Meaning |
|-----------|---------|
Expand All @@ -50,6 +50,7 @@ one that stalls to the 120 s timeout — clip length is not the driver, editor c

## Related repo context

- `docs/active/editor-codec-churn/IMPLEMENTATION.md` — root-cause analysis of the churn/timeout.
- `docs/diagnostics/crashlytics-issue-3a506c4e-verification.md` — the two Crashlytics issues.
- [`docs/lessons_learned/023-media-pipeline-stages-must-count-output-samples.md`](../../../../docs/lessons_learned/023-media-pipeline-stages-must-count-output-samples.md) — codec churn / output-sample counting
- [`docs/lessons_learned/020-imported-clips-hdr-codec-and-reverse-failure-recovery.md`](../../../../docs/lessons_learned/020-imported-clips-hdr-codec-and-reverse-failure-recovery.md) — Crashlytics issues `3a506c4e` / `b09e527`
- `ReverseCrashlytics.kt` — custom keys and non-fatal recording
- Memory `project-trim-handle-touch-sensitivity-bug` — why the trim handles fight you.
61 changes: 61 additions & 0 deletions .github/workflows/doc-layout.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
name: Doc layout

# Hard gate: new Markdown files must live under docs/ (except root README.md and CLAUDE.md).
# Design: docs/README.md § Enforcement

on:
pull_request:
workflow_dispatch: {}

permissions:
contents: read

jobs:
markdown-placement:
name: New .md file placement
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0

- name: Fail on new Markdown outside docs/
run: |
if [ -n "${{ github.event.pull_request.base.sha }}" ]; then
BASE='${{ github.event.pull_request.base.sha }}'
HEAD='${{ github.event.pull_request.head.sha }}'
else
git fetch --no-tags --depth=1 origin "${{ github.event.repository.default_branch }}" || true
BASE="origin/${{ github.event.repository.default_branch }}"
HEAD='HEAD'
fi

ADDED=$(git diff --name-only --diff-filter=A "$BASE" "$HEAD" -- '*.md' || true)
if [ -z "$ADDED" ]; then
echo "No new Markdown files in this diff."
exit 0
fi

echo "New Markdown files:"
echo "$ADDED"

VIOLATIONS=""
for f in $ADDED; do
case "$f" in
README.md|CLAUDE.md)
;;
docs/*)
;;
*)
VIOLATIONS="${VIOLATIONS}${f}\n"
;;
esac
done

if [ -n "$VIOLATIONS" ]; then
echo "::error::New Markdown must live under docs/ (except root README.md and CLAUDE.md)."
printf '%b' "$VIOLATIONS"
exit 1
fi

echo "All new Markdown files are in allowed locations."
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ keystore.properties

# Personal local-only notes (signing playbook, passwords reminders, etc.) — never commit
local/
docs/local/

# Files generated by Gradle
.gradle
Expand Down
16 changes: 6 additions & 10 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ Show reasoning, not just conclusions. I value breadth and rigor equally — cast

When operating in a specific subfolder that has its own CLAUDE.md, respect that folder's voice and approach. The root CLAUDE.md (this file) provides defaults; subfolder overrides take precedence.

All project documentation (`.md` files) belongs in the `docs/` directory — not the project root. The only exceptions are `CLAUDE.md` and `README.md` which live at the root by convention.
All project documentation (`.md` files) belongs in the `docs/` directory — not the project root. The only exceptions are `CLAUDE.md` and `README.md` which live at the root by convention. **Folder map and placement rules:** [`docs/README.md`](docs/README.md) (markdown layout, image assets, gitignored `docs/local/` for private notes).

## Architecture Snapshot

Expand All @@ -83,7 +83,7 @@ All project documentation (`.md` files) belongs in the `docs/` directory — not
| Build | Gradle 9.0.0, AGP 8.13.2 | — |
| Target | compileSdk 36, minSdk 26, targetSdk 36 | — |

> **SDK status (shipped via [Issue #7](https://github.com/stozo04/OpenLoop/issues/7)):** the app targets **API 36 (Android 16)** — `compileSdk`/`targetSdk` 36, `minSdk` stays 26 — clearing Google Play's target-API floor (currently API 35). The upgrade also moved to Kotlin 2.3.21 + the Compose Compiler Gradle plugin (required by the latest CameraX/Media3), and the native libraries are 16 KB page-aligned (uncompressed packaging). Behavior-change detail: [`docs/android-16/`](docs/android-16/README.md). Play's requirement: [Target API Level Requirements](https://developer.android.com/google/play/requirements/target-sdk).
> **SDK status (shipped via [Issue #7](https://github.com/stozo04/OpenLoop/issues/7)):** the app targets **API 36 (Android 16)** — `compileSdk`/`targetSdk` 36, `minSdk` stays 26 — clearing Google Play's target-API floor (currently API 35). Behavior changes: [Android 16 behavior changes](https://developer.android.com/about/versions/16/behavior-changes-16) and `ANDROID_STANDARDS.md` §11. Play's requirement: [Target API Level Requirements](https://developer.android.com/google/play/requirements/target-sdk).

### Source Layout

Expand Down Expand Up @@ -138,17 +138,13 @@ All design tokens, storage patterns, testing strategy, and engineering decisions

| Document | Purpose |
|----------|--------|
| [`docs/README.md`](docs/README.md) | **Documentation layout** — where every `.md` and doc image belongs; enforcement rules |
| `docs/DEFINITION_OF_DONE.md` | **The "Ready for PR" verification gate** — build + test + *run the app + screenshot* before anything is called done. Non-negotiable for non-trivial changes. |
| `docs/lessons_learned/` | **Distilled rules from past PR reviews and bugs. Read every file at session start — see "Required Reading" above.** |
| `docs/PRD-mission-control.md` | **Authoritative architecture and component specs.** Read before any structural change. |
| `docs/TEST_COVERAGE.md` | **Testing strategy and inventory.** Defines test directories, pyramid, frameworks, coroutine testing, current coverage, and gaps. Sourced from Google docs. **OEM lanes:** [`docs/guides/oem-regression-testing.md`](guides/oem-regression-testing.md). |
| `docs/TEST_COVERAGE.md` | **Testing strategy and inventory.** Defines test directories, pyramid, frameworks, coroutine testing, current coverage, and gaps. Sourced from Google docs. **OEM lanes:** [`docs/guides/oem-regression-testing.md`](docs/guides/oem-regression-testing.md). |
| `docs/ANDROID_STANDARDS.md` | **Google Android best practices.** Non-negotiable standards with links to official specs. Consult before introducing new patterns or libraries. §11 covers Android-16 / target-36 rules (now in force — the app targets 36 as of Issue #7). |
| `docs/STATIC_ANALYSIS.md` | **The "Inspect Code" merge gate.** How OpenLoop reproduces Android Studio's two inspection engines headlessly — Engine 1 (Android Lint, automated by the pr-reviewer skill) and Engine 2 (IDE inspections + proofreading, run locally). Exact commands, the `lint-baseline.xml` policy, and severity mapping. |
| `docs/android-16/` | **Android 16 (API 36) upgrade knowledge hub.** Per-page summaries of Google's Android 16 docs, each with an OpenLoop impact verdict and the official source URL. Durable reference for the `targetSdk 36` upgrade (Issue #7) — does not move to `completed/`. |
| `docs/active/` | **Active feature folders.** Each feature gets a folder with at least one IMPLEMENTATION.md. See `docs/active/README.md` for the convention. |
| `docs/completed/` | **Shipped features.** Moved here from `docs/active/` after merge to main. |
| `docs/guides/` | **Plain-English how-to guides.** Beginner-friendly walkthroughs (e.g. `jetpack-datastore-explained.md`, **`oem-regression-testing.md`** — API 34 / Samsung / LG regression lanes). |
| `docs/guides/` | **Plain-English how-tos and durable reference** (reverse algorithm, Robolectric, OEM lanes). Index: [`docs/guides/README.md`](docs/guides/README.md). |
| `docs/play-store/` | **Play Console submission pack** — privacy policy, data safety, store listing copy, signing. |
| `.github/` | PR template, branch naming (`feature/<short-description>`), and workflow conventions. |


Words of wisdom from a previous Claude `HEY_CLAUDE_ITS_ME.md`.
89 changes: 0 additions & 89 deletions GOOGLE_PLAY_PRODUCTION_AUDIT.md

This file was deleted.

Loading