From 7aca10b6d043996bbe65e77b0f7681825e0f9c97 Mon Sep 17 00:00:00 2001 From: Claw Date: Sun, 19 Jul 2026 10:14:13 -0700 Subject: [PATCH] F-080: root principles + P8 implementation alignment tickets MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Codify Bazel-like / one-global-way / explicit+tooling axioms in VISION, README, AGENTS, GETTING-STARTED. Board P8: F-081–F-085 for call-site, config path, deps house style, fleet tooling, full-tree audit. F-071 remains top coding priority. --- AGENTS.md | 18 +++++++++++++++ README.md | 8 ++++++- TICKETS.md | 50 ++++++++++++++++++++++++++++++----------- docs/GETTING-STARTED.md | 4 ++++ docs/PROGRESS.md | 15 +++++++++++++ docs/VISION.md | 29 ++++++++++++++++++++++++ 6 files changed, 110 insertions(+), 14 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index c110b1cd..0d515e01 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -6,6 +6,24 @@ Repo: `formatools/forma` (local: `/Users/claw/work/forma`) Ship Forma as a **working Android product**, then **forma-core** extraction, then **JVM**, then **Bazel**. Full vision: `docs/VISION.md`. Prioritized work: `TICKETS.md`. +## Root principles (axioms — do not re-litigate) + +Full text: `docs/VISION.md` § Root principles. + +1. **Bazel-like rules** — configure once on the type; call sites = minimal static attrs; type behavior **auto-applies**. +2. **One global way** — one supported approach per concern, project-wide (scale to large orgs). Extensibility = extend shared types/config, not module-local Gradle. +3. **Explicit structure + tooling** — declare boundaries; invest in check/generate/migrate for fleet changes. + +### Consequences + +- Flat, role-typed graph; no generic buckets (`androidLibrary` removed). +- Composition only at `androidApp` / `androidBinary` / JVM `binary`; `impl` ↛ `impl`. +- Closed dependency matrix (`docs/DEPENDENCY-MATRIX.md`). +- External plugins type-owned (`docs/TARGET-PLUGINS.md`); never `.withPlugin` / free-form plugin id lists. +- Portable forma-core; platforms adapt. + +**Reject without discussion:** per-module plugin shopping, builder chains for identity, dual happy paths for the same concern, unrestricted deps, restoring `androidLibrary`. + ## Hard rules 1. Work **only** from `TICKETS.md` priority order. Pick the top `todo` / continue `in_progress` ticket. diff --git a/README.md b/README.md index 57f13efe..ce5c9a2c 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,12 @@ structured, type-safe and guided way to declare your project structure. Distribu developers to shift focus from `Build Configuration` to `Project Structure Declaration`, abstracting away build configuration complexity. +**Root principles** (full text: [`docs/VISION.md`](docs/VISION.md)): + +1. **Bazel-like rules** — configure once on the target type; call sites use a minimal set of static attributes; type behavior auto-applies. +2. **One global way** — one supported approach per concern for the whole project (built for large orgs). +3. **Explicit structure + tooling** — declare boundaries openly; tooling makes fleet-wide change reliable. + - You don't need to be a gradle expert anymore - Get rid of project configuration bad practices - Type-safe, single method configuration for your targets, no room for error @@ -25,7 +31,7 @@ configuration complexity. - Target types - enforce scalable project structure - High-performance builds: Gradle best practices are applied automatically - Dependencies framework - helps developers to understand and deal with transitive dependencies hell -- Extensible - be the expert when you need to! +- Extensible via the **shared type/config system** (not per-module Gradle dialects) - And much more... ⚠️ We are using `target` term to express application components(e.g. modules or projects, depending in the context) diff --git a/TICKETS.md b/TICKETS.md index 7a6d84cb..8c2629de 100644 --- a/TICKETS.md +++ b/TICKETS.md @@ -4,6 +4,16 @@ Status legend: `todo` | `in_progress` | `blocked` | `done` Update this file when picking or finishing work. Cron workers must pick the **highest priority open ticket** that is not blocked. +## Root goals (implementation bar) + +Every open ticket below must move the product toward: + +1. **Bazel-like rules** — configure once on the type; call sites = minimal static attrs; type behavior auto-applies. +2. **One global way** — single supported approach per concern, project-wide (scale to large orgs). +3. **Explicit structure + tooling** — declare boundaries openly; invest in check/generate/migrate so fleet changes stay reliable. + +Canonical write-up: `docs/VISION.md` § Root principles. Plugins design: `docs/TARGET-PLUGINS.md`. + ## P0 — Bootstrap (Android product baseline) | ID | Status | Title | Notes | @@ -72,20 +82,33 @@ encourages dumping mixed concerns into one bucket. Prefer specific targets. | F-062 | done | Reimplement progressive examples / skills without `androidLibrary` | `examples/android/04` + agent skills + README curriculum | | F-063 | done | Hard-remove `androidLibrary` target (after consumers migrated) | DSL + `android.library` type/registry/restrictions removed; JVM `library` + AGP feature helper kept; matrix/docs updated | -## P7 — Target plugins API (uniform external plugins) +## P7 — Target plugins (type-owned, auto-apply) + +Close the biggest call-site / multi-way gap: chain `withPlugin`. Design: +`docs/TARGET-PLUGINS.md`. Serves root goals **1** (Bazel call sites) and **2** +(one way: type owns plugin). GH #36 → F-073. + +| ID | Status | Title | Notes | +|----|--------|-------|-------| +| F-070 | done | Design type-owned plugins API | Bazel north star; type owns plugin; auto-apply; reject free-form lists + call-site binding re-selection | +| F-071 | todo | **Implement** type→plugin registry + auto-apply; `targetPlugin` / `deriveTargetType` | Unit tests: type with plugin applies with **zero** call-site plugin API; plugins build green; shims OK | +| F-072 | todo | Migrate sample to derived types (e.g. `navigationRes`); hard-deprecate chain | Zero `.withPlugin` in tree; `TargetBuilder`/`PluginWrapper` `@Deprecated` or removed; application green | +| F-073 | todo | User docs + progressive example + agent skill; close GH #36 | Call sites attributes-only; registration/type layer documented | + +## P8 — Principle alignment (implementation matches goals) -Replace chain-based `TargetBuilder.withPlugin` / `PluginWrapper` with a -**Bazel-like** model: plugin identity on the **target type** (static extend of -pre-defined types **or** derived custom type); call sites are attributes-only and -**auto-apply** type plugins. Design: `docs/TARGET-PLUGINS.md`. GH #36. -**Not** free-form plugin ids or per-callsite `pluginConfig(binding)`. +Close remaining gaps where code/docs still allow **multiple ways**, **fat call +sites**, or **missing fleet tooling**. **F-071 remains the top coding priority** +(P7 before deeper P8 unless a ticket is pure docs). | ID | Status | Title | Notes | |----|--------|-------|-------| -| F-070 | done | Design uniform target plugins API + deprecation plan | `docs/TARGET-PLUGINS.md` — Bazel north star; type owns plugin; call sites auto-apply; config = rule attrs / type-associated config only. Rejected free-form lists **and** call-site binding re-selection | -| F-071 | todo | Type→plugin registry + auto-apply in DSLs; `targetPlugin` / `deriveTargetType` hooks | No call-site plugin ids; unit tests prove auto-apply | -| F-072 | todo | Path B sample migration (e.g. `navigationRes`); deprecate `TargetBuilder` / `PluginWrapper` | Bazel-flat call sites; zero `.withPlugin` | -| F-073 | todo | Docs + progressive example + agent skill; close GH #36 | §3 Bazel mapping in user docs | +| F-080 | done | Codify root principles in product docs | `VISION.md` § Root principles + README + `AGENTS.md` + GETTING-STARTED; board P8 added | +| F-081 | todo | Call-site surface audit: `Unit` returns, no builder chains, minimal attrs | All Android/JVM target DSLs return `Unit`; remove `TargetBuilder` after F-072; inventory optional call-site flags (`compose`, `viewBinding`, …) — keep only as declared rule attrs with **project-global defaults**, not ad-hoc structure | +| F-082 | todo | One global configuration path | Remove/finish-kill deprecated `Project.androidProjectConfiguration`; document `extraPlugins` as **classpath only** (not per-module apply); single settings/store story | +| F-083 | todo | One project-global external-deps convention | House style: version catalog **or** typed catalogs as the sample+docs standard; other path = advanced/legacy note, not dual happy path (`DEPS-CATALOG.md`) | +| F-084 | todo | Fleet tooling for explicit graphs (check / generate / migrate) | Principle 3 at scale: tighten includer/depgen/bazel-check; design+spike migrate helpers for renames/type changes; related GH **#54**. Reliable large refactors without hand-editing thousands of modules | +| F-085 | todo | Full-tree principle audit: sample + examples + agent skills | After F-072/F-081: no chain APIs, no dual styles taught, call sites minimal; fix stragglers | ## Backlog (lower priority / historical GitHub) @@ -96,14 +119,15 @@ Keep for reference; do not start unless higher tickets done or user prioritizes: - GH #88 BuildFeatures support - GH #82 Version code/name in binary - GH #77 transitiveDeps extension -- GH #54 Generate target structure from minimal config +- GH #54 Generate target structure from minimal config → **theme under F-084** - GH #51 Support build types - GH #46 New navigation system - GH #44/#43 Hybrid targets/config examples -- GH #36 Docs for external plugins → **P7 / F-070–F-073** (`docs/TARGET-PLUGINS.md`) -- GH #126 Target features configuration options +- GH #36 Docs for external plugins → **P7 / F-070–F-073** +- GH #126 Target features configuration options → consider under **F-081** - GH #111 Gradle project as buildscript classpath - GH #103 Java 8+ API on Android API ≤26 +- **F-019** AGP 9 / absolute-latest AndroidX — **explicit OK only** (not on board until requested) ## How workers update this file diff --git a/docs/GETTING-STARTED.md b/docs/GETTING-STARTED.md index 5d674ddb..65196462 100644 --- a/docs/GETTING-STARTED.md +++ b/docs/GETTING-STARTED.md @@ -6,6 +6,10 @@ Forma is a **meta build system** for Android (Gradle plugin). You declare rules. Forma applies plugins, shared Android settings, and **dependency visibility validation** for you. +**Root principles** (see [`VISION.md`](VISION.md)): (1) Bazel-like rules — configure +once on the type, minimal call-site attrs; (2) one global way project-wide; (3) +explicit structure, with tooling for large-scale change. + This tutorial gets you from zero to a working multi-target Android app. For the full multi-feature reference layout, see [SAMPLE-APP.md](SAMPLE-APP.md). diff --git a/docs/PROGRESS.md b/docs/PROGRESS.md index de22034a..f353ccb2 100644 --- a/docs/PROGRESS.md +++ b/docs/PROGRESS.md @@ -2,6 +2,21 @@ Newest entries first. +## 2026-07-19 — P8 board: principle-alignment tickets + F-080 docs + +- **User ask:** create tickets to update implementation to match Forma goals (3 root principles) +- **Tickets added (P8):** + - **F-080** `done` — codify principles in VISION/README/AGENTS/GETTING-STARTED + - **F-081** call-site surface audit (Unit returns, minimal attrs) + - **F-082** one global configuration path + - **F-083** one external-deps house style + - **F-084** fleet tooling check/generate/migrate (GH #54 theme) + - **F-085** full-tree sample/examples/skills audit +- **P7 unchanged priority:** **F-071** still top coding ticket (type-owned plugins) +- **TICKETS.md** top section = root goals bar for all workers +- **Product code:** none this slice +- **Next:** F-071 implement + ## 2026-07-19 — F-070 revised again: Bazel-like call sites - **Ticket:** F-070 design correction (PR #185 update) diff --git a/docs/VISION.md b/docs/VISION.md index 9f3c1221..bbc70daf 100644 --- a/docs/VISION.md +++ b/docs/VISION.md @@ -4,6 +4,34 @@ Make **Forma** a working product for **Android** first, then adapt the same approach for **JVM applications**, then for **Bazel**. +## Root principles (product axioms) + +These are the bar for every API and implementation change. Inferable from the +README meta-build pitch; stated here so they cannot drift. + +1. **Bazel-like rules** — Configure behavior **once** on the target type (rule). + Call sites use a **minimal set of static attributes** (package, deps, declared + rule fields). Using a type always gets that type’s behavior (plugins, features, + content rules, matrix). No per-module tool shopping. +2. **One global way** — Built to scale to very large orgs (thousands of developers). + There is **one** supported way to express a given concern, **global for the + entire project**. Extensibility means extending the shared type/config system, + not inventing module-local Gradle dialects. +3. **Everything is explicit** — Structure and boundaries are declared, not implied + by hidden convention soup. Tradeoff: more configuration at the **type / project** + layer. Remedy: **tooling** so large-scale changes stay easy and reliable + (check / generate / migrate — includer, depgen, adapters, future fleet tools). + +### Consequences (do not treat as separate products) + +- **Flat, role-typed graph** — most specific role; no generic buckets (`androidLibrary` removed). +- **Composition only at roots** — `androidApp` / `androidBinary` / JVM `binary`; `impl` ↛ `impl`. +- **Closed dependency matrix** — allow-listed project edges only. +- **Portable forma-core** — types, restrictions, validation, registry; platforms adapt. +- **External plugins** — type-owned, auto-apply; see [`TARGET-PLUGINS.md`](TARGET-PLUGINS.md). + +Implementation debt vs these axioms is tracked under **P7–P8** in `TICKETS.md`. + ## Core product principle — keep structure flat Forma exists to **protect a flat, role-typed module graph**. Each target type is a @@ -51,6 +79,7 @@ Concrete stacks built **on** forma-core: 4. **Bazel** — design + implement adapter once core is stable (see [`docs/BAZEL-ADAPTER.md`](BAZEL-ADAPTER.md) for the F-040 mapping design). 5. **Flat-structure hardening** — deprecate/remove generic targets that undermine role typing (P6 / F-060+). 6. **Uniform target plugins** — Bazel-like: plugin on the **target type**, auto-apply on every call site; call sites are attributes-only; deprecate chain `withPlugin` (P7 / F-070+; [`TARGET-PLUGINS.md`](TARGET-PLUGINS.md)). +7. **Principle-alignment implementation** — close remaining gaps vs root principles (P8 / F-080+). ## Working principles