diff --git a/.skills/speckit/SKILL.md b/.skills/speckit/SKILL.md index bdbb8459e6..a3a2bcd5f2 100644 --- a/.skills/speckit/SKILL.md +++ b/.skills/speckit/SKILL.md @@ -108,14 +108,14 @@ 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.3.3) enforces 7 principles: +Current constitution (v1.3.4) 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. **Documentation Freshness** — User-facing changes update `docs/` (in-app browser, Jekyll, Docusaurus) with `last_updated` frontmatter; blocking CI gate +6. **Documentation Freshness** — User-facing changes update `docs/en/` (in-app browser, Jekyll, Docusaurus) with `last_updated` frontmatter; author-enforced, the check scripts are not wired into CI 7. **Verify Before Push** — Local verification before any `git push` ## Extension Hooks diff --git a/.specify/memory/agent-governance.md b/.specify/memory/agent-governance.md index 9695b2f057..8c1cf560ae 100644 --- a/.specify/memory/agent-governance.md +++ b/.specify/memory/agent-governance.md @@ -2,6 +2,17 @@ ## Final Output @@ -21,16 +32,18 @@ Sync Impact Report ## Repository Evidence - README: `README.md` -- Package manifest: `Gemfile`, `build.gradle.kts` -- Lockfiles: `Gemfile.lock` -- Task runners: none detected -- CI workflows: `.github/workflows/create-or-promote-release.yml`, `.github/workflows/dependency-submission.yml`, `.github/workflows/docs-deploy.yml`, `.github/workflows/docs-governance.yml`, `.github/workflows/docs-release.yml`, `.github/workflows/main-check.yml`, `.github/workflows/merge-queue.yml`, `.github/workflows/models_issue_triage.yml`, `.github/workflows/models_pr_triage.yml`, `.github/workflows/moderate.yml`, `.github/workflows/post-release-cleanup.yml`, `.github/workflows/pr_enforce_labels.yml`, `.github/workflows/promote.yml`, `.github/workflows/publish-core.yml`, `.github/workflows/pull-request-target.yml`, `.github/workflows/pull-request.yml`, `.github/workflows/release.yml`, `.github/workflows/reusable-check.yml`, `.github/workflows/scheduled-updates.yml`, `.github/workflows/stale.yml`, `.github/workflows/sync-android-docs.yml`, `.github/workflows/update-changelog.yml` -- Source paths: `app/`, `scripts/` -- Test paths: `specs/` +- Package manifest: `build.gradle.kts`, `settings.gradle.kts`, `gradle/libs.versions.toml` + (`docs/Gemfile` + `docs/Gemfile.lock` belong to the Jekyll docs site only) +- Task runners: Gradle wrapper (`gradlew`), convention plugins in `build-logic/` +- CI workflows: `.github/workflows/create-or-promote-release.yml`,`.github/workflows/dependency-graph-submit.yml` `.github/workflows/docs-deploy.yml`,`.github/workflows/docs-release.yml` `.github/workflows/main-check.yml`,`.github/workflows/merge-queue.yml` `.github/workflows/msstore-publish.yml`,`.github/workflows/post-release-cleanup.yml` `.github/workflows/pr-closed-cleanup.yml`,`.github/workflows/promote.yml` `.github/workflows/pull-request-target.yml`,`.github/workflows/pull-request.yml` `.github/workflows/release.yml`,`.github/workflows/reusable-check.yml` `.github/workflows/scheduled-baseline.yml`,`.github/workflows/scheduled-updates.yml` `.github/workflows/stale.yml`,`.github/workflows/update-changelog.yml` `.github/workflows/verify-flatpak.yml`,`.github/workflows/winget-publish.yml` +- Source paths: `androidApp/`, `desktopApp/`, `core/`, `feature/`, `build-logic/`, `scripts/` +- Test paths: `**/src/commonTest/`, `**/src/jvmTest/`, `**/src/androidHostTest/`, + `screenshot-tests/`, `docs-screenshots/`, `baselineprofile/`, `core/konsist/` - Repository areas: (see "Repository Areas" section below for top-level listing) - Existing agent context files: `.github/copilot-instructions.md`, `AGENTS.md`, `CLAUDE.md`, `GEMINI.md` -- Repository-local skills: `.agent_refs/mqttastic-client-kmp/.github/skills/mqtt-kmp/SKILL.md`, `.skills/ci-cost-control/SKILL.md`, `.skills/code-review/SKILL.md`, `.skills/compose-ui/SKILL.md`, `.skills/design-standards/SKILL.md`, `.skills/implement-feature/SKILL.md`, `.skills/kmp-architecture/SKILL.md`, `.skills/navigation-and-di/SKILL.md`, `.skills/new-branch/SKILL.md`, `.skills/project-overview/SKILL.md`, `.skills/speckit/SKILL.md`, `.skills/testing-ci/SKILL.md` -- MCP configs: `.agent_refs/firmware/src/modules/Telemetry/Sensor/MCP9808Sensor.cpp`, `.agent_refs/firmware/src/modules/Telemetry/Sensor/MCP9808Sensor.h`, `androidApp/build/intermediates/incremental/googleDebug-mergeJavaRes/zip-cache/ut0r9CiGRq6mCprTK2blRg==`, `app/build/intermediates/incremental/fdroidDebug-mergeJavaRes/zip-cache/mcpnRT6ZHkD92YpTv5y52w==`, `app/build/intermediates/incremental/googleDebug-mergeJavaRes/zip-cache/mcpnRT6ZHkD92YpTv5y52w==`, `app/build/intermediates/incremental/googleDebug-mergeJavaRes/zip-cache/ut0r9CiGRq6mCprTK2blRg==` +- Contextual instruction files: `.github/instructions/*.instructions.md` +- Repository-local skills: `.claude/skills/baseline/SKILL.md`,`.claude/skills/crashlytics-triage/SKILL.md` `.claude/skills/pr/SKILL.md`,`.claude/skills/proto-bump/SKILL.md` `.skills/ci-cost-control/SKILL.md`,`.skills/code-review/SKILL.md` `.skills/compose-ui/SKILL.md`,`.skills/design-standards/SKILL.md` `.skills/implement-feature/SKILL.md`,`.skills/kmp-architecture/SKILL.md` `.skills/navigation-and-di/SKILL.md`,`.skills/new-branch/SKILL.md` `.skills/project-overview/SKILL.md`,`.skills/speckit/SKILL.md` `.skills/testing-ci/SKILL.md` +- MCP configs: `.mcp.json` - Active integration: `copilot` - Resolved context file: `AGENTS.md` @@ -40,14 +53,21 @@ Sync Impact Report review the parent area's context for impact. Top-level directories require review before changing linked areas; child directories change with their parent. -**Top-level areas requiring review**: `.agent_memory/`, `.agent_plans/`, `.agent_refs/`, -`.github/`, `.specify/`, `androidApp/`, `app/`, `build-logic/`, `config/`, `core/`, -`desktop/`, `desktopApp/`, `docs/`, `docs-screenshots/`, `docs-site/`, `fastlane/`, `feature/`, -`gradle/`, `ios/`, `iosApp/`, `offline-repository/`, `screenshot-tests/`, `scripts/`, `specs/` +**Top-level areas requiring review**: `.claude/`, `.github/`, `.skills/`, `.specify/`, +`androidApp/`, `baselineprofile/`, `build-logic/`, `config/`, `core/`, `desktopApp/`, +`docs/`, `docs-screenshots/`, `fastlane/`, `feature/`, `gradle/`, `obtainium/`, +`screenshot-tests/`, `scripts/`, `specs/` + +`.agent_memory/` and `.agent_plans/` are git-ignored agent scratch — never staged, never +reviewed. ## Development Commands -- none detected +- Baseline: `./gradlew spotlessApply spotlessCheck detekt assembleDebug test allTests` +- Cross-target compile: `./gradlew kmpSmokeCompile` +- After adding strings: `python3 scripts/sort-strings.py` +- Docs checks: `node scripts/check-doc-coverage.js`, `node scripts/validate-doc-links.js` +- Full detail: `.skills/testing-ci/SKILL.md` ## Scope diff --git a/.specify/memory/constitution.md b/.specify/memory/constitution.md index 5fc898ec08..ada56b2a17 100644 --- a/.specify/memory/constitution.md +++ b/.specify/memory/constitution.md @@ -1,18 +1,36 @@ # Meshtastic Android (KMP) Constitution @@ -27,8 +45,8 @@ MUST be used in place of JVM/Android-specific APIs: - MUST use Okio (not `java.io`), Ktor (not `java.net`/OkHttp in common), Mutex/atomicfu (not `java.util.concurrent`), Room KMP, DataStore KMP, and Koin 4.2+. - MUST NOT import `java.*` or `android.*` in any `commonMain` module. -- Platform-specific implementations belong in `androidMain`/`desktopMain` actual - declarations only. +- Platform-specific implementations belong in `androidMain`/`jvmMain` actual + declarations only (there is no `desktopMain` source set; Desktop is the `jvm` target). ### II. Zero Lint Tolerance @@ -99,20 +117,30 @@ Governance rules: - Every doc page MUST include a `last_updated` frontmatter field (YYYY-MM-DD). Update this field whenever page content changes. -- PRs that modify user-facing UI source files MUST update the corresponding doc page(s) - or apply the `skip-docs-check` label with justification. The docs staleness check is a - **blocking** CI gate. -- Internal cross-references between doc pages and image paths MUST be validated; broken - links fail the `docs-governance` workflow. -- Every user-facing feature module MUST have corresponding documentation in `docs/user/` - or `docs/developer/`. Coverage is checked by `scripts/check-doc-coverage.js`. -- Pages older than 180 days without updates trigger an advisory freshness warning. -- New doc pages MUST be registered in `DocBundleLoader.kt` (in-app index), and added to - the `KNOWN_*_SLUGS` sets in `sync-android-docs.js` (Docusaurus link resolution). - Jekyll picks up new pages automatically via `_config.yml` scope-based defaults. +- A PR that changes user-facing behaviour MUST update the corresponding page(s) under + `docs/en/user/` or `docs/en/developer/`, or state in the PR description why no page + changed. +- Every user-facing feature module MUST have a corresponding page under `docs/en/user/` + or `docs/en/developer/`. +- New doc pages MUST be registered in `DocBundleLoader.kt` (the in-app index) with a + `navOrder`. Jekyll picks new pages up automatically via `_config.yml` scope-based + defaults, and `sync-android-docs.js` discovers slugs from the source tree — neither + needs a manual registration step. - Image references MUST use root-relative paths (`/assets/screenshots/filename.png`) so they resolve correctly in both Jekyll and the in-app renderer. The sync script rewrites these to Docusaurus paths automatically. +- English pages are the only ones written by hand. `docs//user/` is downloaded + from Crowdin (`crowdin.yml`) — never hand-edit a locale page; deleting an English page + means deleting its locale copies in the same commit. + +Verification tooling (run on demand; **none of these is wired into CI** — an inaccurate +page will not fail a build, which is why the rules above are on the author): + +```bash +node scripts/check-doc-coverage.js # every user-facing feature module has a page +node scripts/validate-doc-links.js # internal cross-references and image paths resolve +node scripts/check-doc-freshness.js # advisory: pages >180 days old, or missing last_updated +``` ### VII. Verify Before Push @@ -194,4 +222,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.3 | **Ratified**: 2026-05-07 | **Last Amended**: 2026-06-22 +**Version**: 1.3.4 | **Ratified**: 2026-05-07 | **Last Amended**: 2026-08-27 diff --git a/.specify/templates/checklist-template.md b/.specify/templates/checklist-template.md index 1a801d7a1b..53023a62a3 100644 --- a/.specify/templates/checklist-template.md +++ b/.specify/templates/checklist-template.md @@ -27,7 +27,7 @@ - [ ] 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? 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 (Documentation Freshness): User-facing changes update `docs/` (with `last_updated`) or justified `skip-docs-check`? [Consistency] +- [ ] CHK006 — Principle VI (Documentation Freshness): User-facing changes update `docs/en/` (with `last_updated`), or the PR says why not? `validate-doc-links.js` + `check-doc-coverage.js` run locally? [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 d4554d2762..4a0d4914e8 100644 --- a/.specify/templates/plan-template.md +++ b/.specify/templates/plan-template.md @@ -53,9 +53,10 @@ - **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. 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. +- **VI. Documentation Freshness**: If user-facing behaviour changes, confirm the corresponding + `docs/en/` page(s) are updated (with `last_updated` frontmatter), or state why none did. + Nothing enforces this in CI — run `node scripts/validate-doc-links.js` and + `node scripts/check-doc-coverage.js` yourself. - **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.