From 2ff7ecf2d94b80483ad0867dc125ebcfbc9d1e29 Mon Sep 17 00:00:00 2001 From: James Rich <2199651+jamesarich@users.noreply.github.com> Date: Mon, 22 Jun 2026 15:23:59 -0500 Subject: [PATCH] docs: de-submodule protos, sync constitution to v1.3.3, prune stale governance refs (#5905) Co-authored-by: Claude Opus 4.8 Signed-off-by: James Rich --- .claude/settings.json | 3 +-- .github/copilot-instructions.md | 3 +-- .skills/design-standards/SKILL.md | 15 +++++++------- .skills/new-branch/SKILL.md | 13 ++++++------ .skills/speckit/SKILL.md | 5 +++-- .specify/memory/constitution.md | 25 ++++++++++++++---------- .specify/templates/checklist-template.md | 5 +++-- .specify/templates/plan-template.md | 7 +++++-- .specify/templates/spec-template.md | 2 +- .specify/templates/tasks-template.md | 2 +- AGENTS.md | 3 ++- CLAUDE.md | 2 +- 12 files changed, 48 insertions(+), 37 deletions(-) diff --git a/.claude/settings.json b/.claude/settings.json index 76f07396d..1727aea7f 100644 --- a/.claude/settings.json +++ b/.claude/settings.json @@ -2,8 +2,7 @@ "$comment": "Team-wide Claude Code config. (1) Read guards: Claude does NOT read .aiexclude/.copilotignore, so the big-file protections live here. 'deny' = never read (Crowdin-managed translations); 'ask' = prompt first (big files rarely needed in full — prefer .skills/compose-ui/strings-index.txt for strings; signing keys should never be read into context). (2) Hooks front-run this repo's own CI gates locally — see .claude/hooks/*.sh for what each does. The pre-bash-guard spotlessApply-on-commit hook is the heaviest (runs gradle at commit time); remove its PreToolUse entry if it's too eager for your workflow.", "permissions": { "deny": [ - "Read(**/composeResources/**/values-*/*.xml)", - "Read(**/res/values-*/strings.xml)" + "Read(**/composeResources/**/values-*/*.xml)" ], "ask": [ "Read(**/composeResources/**/values/strings.xml)", diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index b72a68c96..6b8f13587 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -4,9 +4,8 @@ ## Build, Test & Lint (essentials) -Requires JDK 21, `ANDROID_HOME`, and the proto submodule. Per fresh clone: +Requires JDK 21 and `ANDROID_HOME`. Per fresh clone: ```bash -git submodule update --init [ -f local.properties ] || cp secrets.defaults.properties local.properties ``` ```bash diff --git a/.skills/design-standards/SKILL.md b/.skills/design-standards/SKILL.md index 91646966f..d0ec5bd1c 100644 --- a/.skills/design-standards/SKILL.md +++ b/.skills/design-standards/SKILL.md @@ -4,23 +4,23 @@ Android-specific guidance for applying the Meshtastic design standards. All visual rules, color palettes, accessibility requirements, and cross-platform conventions live upstream. > **Source of truth:** [`meshtastic/design/standards/`](https://github.com/meshtastic/design/tree/main/standards) -> Read `meshtastic_design_standards_latest.md` for the full spec (colors, M3 mapping, accessibility, units/locale, agent checklist). +> Read `meshtastic_design_standards_latest.md` (a pointer to the current versioned spec — `meshtastic_design_standards_v1_4.md` at time of writing) for the full spec (colors, M3 mapping, accessibility, units/locale, agent checklist). > If this skill diverges from upstream, **upstream wins**. ## 1. How to Use the Standards Before implementing any UI: 1. **Read the upstream standards** — they include a full agent implementation checklist -2. **Check the settings validation doc** — [`meshtastic/design/validation/settings-validation-android.md`](https://github.com/meshtastic/design/blob/main/validation/settings-validation-android.md) has field-by-field validation rules for every config/module setting +2. **Check the settings validation matrix** — [`meshtastic/design/standards/audits/settings-validation-matrix.md`](https://github.com/meshtastic/design/blob/main/standards/audits/settings-validation-matrix.md) has field-by-field validation rules for every config/module setting 3. Apply the Android-specific mappings below ## 2. Android / Compose Mappings ### Theme Tokens The upstream standards define M3 role mappings (Section 8). In this codebase: -- Theme is defined in `core/ui/` — `MeshtasticTheme` composable +- Theme is defined in `core/ui/` — the `AppTheme` composable (`core/ui/src/commonMain/kotlin/org/meshtastic/core/ui/theme/Theme.kt`) - Use M3 tokens (`MaterialTheme.colorScheme.primary`, `.surface`, etc.) — never raw hex values -- Dynamic color (Android 12+): supported in the `google` flavor via `dynamicColorScheme()` +- Dynamic color (Android 12+): on by default via `dynamicColorScheme()` (`AppTheme(dynamicColor = true)` for all flavors); the Android `actual` is gated by SDK ≥ S, while desktop/iOS return null ### Brand Colors → Compose | Standard Name | Hex | Compose Usage | @@ -31,6 +31,8 @@ The upstream standards define M3 role mappings (Section 8). In this codebase: | Error | `#E05252` | `MaterialTheme.colorScheme.error` | | Link | `#9BA8E0` | Blue 400 — for clickable text | +> Raw palette defined in `core/ui/src/commonMain/kotlin/org/meshtastic/core/ui/theme/CustomColors.kt` (e.g. `N800`, `G500`, `G600`, `E500`, `B400`) — reference the M3 token, not the raw `CustomColors` entry, in UI code. + ### Key Rules (Android-specific) - **Icons:** Use `MeshtasticIcons` (from `core/ui/icon/`), not `material.icons.Icons` - **Touch targets:** 44×44dp minimum (M3 default is 48dp — compliant) @@ -39,9 +41,8 @@ The upstream standards define M3 role mappings (Section 8). In this codebase: ## 3. App Icons -- Launcher icons: separate SVGs (foreground/background), 108px square, logo 58px wide/high -- Generate with [Image Asset Studio](https://developer.android.com/studio/write/image-asset-studio#create-adaptive). Name: `ic_launcher2` -- Action bar: `logo/svg/Mesh_Logo_White.svg`, 0% padding, HOLO_DARK theme, named `app_icon` +- Launcher icon: `ic_launcher` — adaptive (`androidApp/src/main/res/mipmap-anydpi/ic_launcher.xml`) with foreground/background layers. The Play-Store listing asset is `androidApp/src/main/ic_launcher2-playstore.png`. +- When regenerating, use [Image Asset Studio](https://developer.android.com/studio/write/image-asset-studio#create-adaptive) and keep the `ic_launcher` resource name. ## 4. Settings Validation Reference diff --git a/.skills/new-branch/SKILL.md b/.skills/new-branch/SKILL.md index 60d81d234..b18d46ce0 100644 --- a/.skills/new-branch/SKILL.md +++ b/.skills/new-branch/SKILL.md @@ -33,8 +33,8 @@ git --no-pager log -1 --oneline ``` ## Branch Naming -Use conventional-commit style prefixes that match the PR title convention in AGENTS.md -``: +Use conventional-commit style prefixes that match the PR title convention in +`.github/copilot-pull-request-instructions.md`: | Prefix | Use for | | :--- | :--- | @@ -65,8 +65,9 @@ Never use plain `--force`. Always `--force-with-lease` to avoid clobbering colla - [ ] `ANDROID_HOME` exported (see AGENTS.md workspace bootstrap). - [ ] Optional: run `./gradlew assembleDebug` once to catch environment regressions before editing. -## Tip: Prefer `/delegate` for Long Audits +## Tip: Delegate Long Audits to a Subagent If the user's opening prompt is a sweeping audit or investigation (e.g. *"audit changes since -v2.7.13 for regressions"*, *"investigate why animations are broken on release"*), consider -suggesting `/delegate` — the GitHub cloud agent can execute the branch + investigation + PR -end-to-end while the user keeps working locally. See AGENTS.md ``. +v2.7.13 for regressions"*, *"investigate why animations are broken on release"*), dispatch the +`Explore` subagent (read-only, broad fan-out) so file dumps stay out of the main context and +you get back just the conclusion; use the `gradle-runner` subagent for heavy `./gradlew` runs. +See CLAUDE.md → "Delegate to keep context lean". diff --git a/.skills/speckit/SKILL.md b/.skills/speckit/SKILL.md index badec3fbf..f1aa94e5b 100644 --- a/.skills/speckit/SKILL.md +++ b/.skills/speckit/SKILL.md @@ -108,14 +108,15 @@ specs/ The project constitution at `.specify/memory/constitution.md` defines non-negotiable principles. All specs, plans, and tasks are validated against it during `/speckit.analyze`. -Current constitution (v1.2.0) enforces 6 principles: +Current constitution (v1.3.3) enforces 7 principles: 1. **KMP Core** — Business logic in `commonMain` only 2. **Zero Lint Tolerance** — `spotlessCheck` + `detekt` must pass 3. **Compose Multiplatform UI** — CMP, not Android-only Compose 4. **Privacy First** — No PII/location/key exposure 5. **Design Standards Compliance** — Review against Meshtastic design standards; cross-platform features must reference an upstream spec from `meshtastic/design/features/` -6. **Verify Before Push** — Local verification before any `git push` +6. **Documentation Freshness** — User-facing changes update `docs/` (in-app browser, Jekyll, Docusaurus) with `last_updated` frontmatter; blocking CI gate +7. **Verify Before Push** — Local verification before any `git push` ## Extension Hooks diff --git a/.specify/memory/constitution.md b/.specify/memory/constitution.md index 56648f6d6..5fc898ec0 100644 --- a/.specify/memory/constitution.md +++ b/.specify/memory/constitution.md @@ -1,13 +1,17 @@ @@ -56,8 +60,9 @@ times: or any debug output. - Secrets MUST be git-ignored and MUST NOT be committed to the repository under any circumstances. -- `core/proto` is a read-only upstream submodule (`meshtastic/protobufs`). MUST NOT modify - `.proto` files directly; proto changes require an upstream issue labeled `upstream`. +- Protobuf models come from the upstream `org.meshtastic:protobufs` Maven dependency (pinned + in `gradle/libs.versions.toml`). MUST NOT hand-edit generated proto; proto changes require + an upstream change and a dependency version bump. ### V. Design Standards Compliance @@ -142,9 +147,9 @@ The following module boundaries and technology choices are fixed for this projec No alternative DI framework may be introduced. - **Navigation**: JetBrains Navigation 3 for multiplatform routing with RESTful deep linking. All navigation MUST use `MeshtasticNavDisplay`. -- **Data Protocol**: Protobuf for device communications (read-only upstream submodule). - Room KMP for local persistence. DataStore for user preferences. -- **Language & Toolchain**: Kotlin 2.3+ targeting JDK 21. Java source files MUST NOT be +- **Data Protocol**: Protobuf for device communications (the `org.meshtastic:protobufs` + Maven dependency). Room KMP for local persistence. DataStore for user preferences. +- **Language & Toolchain**: Kotlin 2.4+ targeting JDK 21. Java source files MUST NOT be introduced in KMP modules. ## Operational Standards @@ -189,4 +194,4 @@ summary derived from this constitution. The files `.github/copilot-instructions. Constitution Check confirming all seven principles were evaluated. Complexity violations require explicit justification in the Complexity Tracking table of the plan document. -**Version**: 1.3.2 | **Ratified**: 2026-05-07 | **Last Amended**: 2026-05-21 +**Version**: 1.3.3 | **Ratified**: 2026-05-07 | **Last Amended**: 2026-06-22 diff --git a/.specify/templates/checklist-template.md b/.specify/templates/checklist-template.md index d819ef262..1a801d7a1 100644 --- a/.specify/templates/checklist-template.md +++ b/.specify/templates/checklist-template.md @@ -25,9 +25,10 @@ - [ ] CHK001 — Principle I (KMP Core): All code in `commonMain`? No `java.*`/`android.*` imports? [Consistency] - [ ] CHK002 — Principle II (Zero Lint Tolerance): `spotlessApply` + `detekt` pass? [Consistency] - [ ] CHK003 — Principle III (CMP UI): Compose Multiplatform composables? `NumberFormatter.format()` for floats? Navigation 3 patterns? [Consistency] -- [ ] CHK004 — Principle IV (Privacy First): No PII/location/key logging? Proto submodule untouched? [Consistency] +- [ ] CHK004 — Principle IV (Privacy First): No PII/location/key logging? Generated proto not hand-edited? [Consistency] - [ ] CHK005 — Principle V (Design Standards): UI reviewed against Meshtastic design standards? Cross-platform features linked to upstream spec in `meshtastic/design/features/`? [Consistency] -- [ ] CHK006 — Principle VI (Verify Before Push): Full verification passing locally? [Consistency] +- [ ] CHK006 — Principle VI (Documentation Freshness): User-facing changes update `docs/` (with `last_updated`) or justified `skip-docs-check`? [Consistency] +- [ ] CHK007 — Principle VII (Verify Before Push): Full verification passing locally? [Consistency] ## [Category 1] diff --git a/.specify/templates/plan-template.md b/.specify/templates/plan-template.md index 95faa7316..d4554d276 100644 --- a/.specify/templates/plan-template.md +++ b/.specify/templates/plan-template.md @@ -49,11 +49,14 @@ Multiplatform patterns, `MeshtasticNavDisplay`/`NavigationBackHandler` where relevant, and pre-formats floats with `NumberFormatter.format()`. - **IV. Privacy First**: Confirm the change does not log or expose PII, location data, - cryptographic keys, or modify the read-only `core/proto` submodule. + cryptographic keys, or hand-edit generated proto (the `org.meshtastic:protobufs` Maven dependency). - **V. Design Standards Compliance**: For any user-facing UI, record how the design was checked against the Meshtastic Client Design Standards. For cross-platform features, link the upstream behavior spec from `meshtastic/design/features/` or justify N/A. -- **VI. Verify Before Push**: Record the exact local verification commands and the expected +- **VI. Documentation Freshness**: If user-facing UI changes, confirm the corresponding + `docs/` page(s) are updated (with `last_updated` frontmatter) or the `skip-docs-check` + label is applied with justification. +- **VII. Verify Before Push**: Record the exact local verification commands and the expected post-push CI check command (`gh pr checks` or `gh run list`) before implementation starts. If any gate cannot be met, the exception MUST be justified in the Complexity Tracking diff --git a/.specify/templates/spec-template.md b/.specify/templates/spec-template.md index 849e38aff..1fcdf549c 100644 --- a/.specify/templates/spec-template.md +++ b/.specify/templates/spec-template.md @@ -172,7 +172,7 @@ - [ ] No PII, location data, or cryptographic keys logged or exposed - [ ] No new network calls that transmit user data -- [ ] Proto submodule (`core/proto`) not modified (read-only upstream) +- [ ] Generated proto not hand-edited (the `org.meshtastic:protobufs` Maven dependency) ## Success Criteria *(mandatory)* diff --git a/.specify/templates/tasks-template.md b/.specify/templates/tasks-template.md index 5bc9eb6f0..34558bdee 100644 --- a/.specify/templates/tasks-template.md +++ b/.specify/templates/tasks-template.md @@ -160,7 +160,7 @@ Examples of foundational tasks (adjust based on your project): - [ ] TXXX [P] Documentation updates in docs/ - [ ] TXXX Code cleanup and refactoring - [ ] TXXX [P] Review user-facing UI against Meshtastic design standards and document any approved deviations -- [ ] TXXX [P] Confirm no logs, telemetry, or config changes expose PII, location data, secrets, or modify `core/proto` +- [ ] TXXX [P] Confirm no logs, telemetry, or config changes expose PII, location data, or secrets - [ ] TXXX [P] Run constitution-required verification (`spotlessCheck`, `detekt`, and relevant compile/test tasks) - [ ] TXXX [P] Additional unit/integration tests (if requested) in the appropriate test source sets - [ ] TXXX Validate quickstart/README or developer workflow docs if contributor workflow changed diff --git a/AGENTS.md b/AGENTS.md index 4ccb053ea..75255b25e 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -6,12 +6,13 @@ You are an expert Android/KMP engineer. Maintain architectural boundaries, use M - **Project Goal:** Decouple business logic from Android for multi-platform (Android, Desktop, iOS). -- **Tech:** Kotlin 2.3+ (JDK 21), Ktor, Okio, Room KMP, Koin 4.2+. +- **Tech:** Kotlin 2.4+ (JDK 21), Ktor, Okio, Room KMP, Koin 4.2+. - **Agent Memory:** Skim the top (most recent) entry of `.agent_memory/session_context.md` for current state — it is capped at ~5 entries; older handovers live in `session_context.archive.md` (read only if you need historical detail). - **Skills Directory (CONSULT THESE FIRST):** - `.skills/project-overview/` - Codebase map, namespacing, **Bootstrap Steps**. - `.skills/kmp-architecture/` - Expect/actual, source-sets, conventions. - `.skills/compose-ui/` - Adaptive UI, **String Resources (consult strings-index.txt first)**. + - `.skills/design-standards/` - **Visual design standards** (brand colors, M3 tokens, MeshtasticIcons, accessibility); upstream `meshtastic/design` is source of truth. - `.skills/navigation-and-di/` - Navigation 3 & Koin annotations. - `.skills/testing-ci/` - Validation commands, **CI Architecture**. - `.skills/ci-cost-control/` - **CI Budgeting & Monitoring**. diff --git a/CLAUDE.md b/CLAUDE.md index a97903bb8..37eda3809 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -10,7 +10,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co - **Think First:** Outline step-by-step reasoning inside `` tags before writing code or shell commands. - **Skills:** Load only the `.skills/` module relevant to the current task — don't read them all. Start with `.skills/project-overview/SKILL.md` (codebase map, bootstrap, troubleshooting). -- **Plan Mode:** Use it for changes spanning multiple modules; write plans to `.agent_plans/` (git-ignored). Skip the Copilot-CLI `` guidance in AGENTS.md — it doesn't apply to Claude Code. +- **Plan Mode:** Use it for changes spanning multiple modules; write plans to `.agent_plans/` (git-ignored). - **Delegate to keep context lean** (this is a 20+ module KMP repo): - **Broad searches** ("where is X used", "find all implementers of Y") → dispatch the `Explore` subagent so file dumps stay out of the main context; you get back the conclusion. - **Gradle builds/tests/lint** → dispatch the `gradle-runner` subagent. A full `assembleDebug`/`allTests` log is thousands of lines; the subagent returns only pass/fail + failing tests. Don't run heavy `./gradlew` tasks inline.