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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ systems like Buck and Bazel.
2. [**JVM getting started**](docs/JVM-GETTING-STARTED.md) — pure JVM tutorial, run the sample, greenfield skeleton with `binary`, `api`/`impl`, target cheat sheet (F-032)
3. [Sample app gold standard](docs/SAMPLE-APP.md) — multi-feature layout to copy
4. [Dependency matrix](docs/DEPENDENCY-MATRIX.md) — what may depend on what
5. [External deps catalogs](docs/DEPS-CATALOG.md) · [Target plugins](docs/TARGET-PLUGINS.md) (type-owned, Bazel-like; example `examples/android/10-target-plugins`) · [Call-site surface](docs/CALL-SITE-SURFACE.md) (Unit DSLs + flag inventory) · [Fleet tooling](docs/FLEET-TOOLING.md) (check/generate/migrate, F-084) · [Compose](docs/COMPOSE.md) · [Environment](docs/ENV.md)
5. [External deps catalogs](docs/DEPS-CATALOG.md) · [Target plugins](docs/TARGET-PLUGINS.md) (type-owned, Bazel-like; example `examples/android/10-target-plugins`) · [Call-site surface](docs/CALL-SITE-SURFACE.md) (Unit DSLs + flag inventory) · [Fleet tooling](docs/FLEET-TOOLING.md) (check/generate/migrate, F-084) · [Principle audit](docs/PRINCIPLE-AUDIT.md) (F-085) · [Compose](docs/COMPOSE.md) · [Environment](docs/ENV.md)
6. [Plugin publish path](docs/PLUGIN-PUBLISH.md) — Portal metadata DSL + release notes (F-016)
7. [Configuration performance](docs/CONFIGURATION-PERFORMANCE.md) — measure + hot-path guidance (F-017 / GH #106)
8. [forma-core public API design](docs/forma-core-api.md) — extraction contract for types / restrictions / registry (F-020)
Expand Down
6 changes: 3 additions & 3 deletions TICKETS.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,8 @@ Close the biggest call-site / multi-way gap: chain `withPlugin`. Design:
## P8 — Principle alignment (implementation matches goals)

Close remaining gaps where code/docs still allow **multiple ways**, **fat call
sites**, or **missing fleet tooling**. P7 (F-070–F-073) and F-081–F-084 are **done**; **F-019 Phase 1 done**.
**Next coding:** **F-085**
sites**, or **missing fleet tooling**. **P7 + P8 (F-070–F-085) done**; **F-019 Phase 1 done**.
**Next coding:** board empty for product principles — promote backlog (AndroidX ceiling, GH issues) or new F-xxx only on user request.

| ID | Status | Title | Notes |
|----|--------|-------|-------|
Expand All @@ -110,7 +110,7 @@ sites**, or **missing fleet tooling**. P7 (F-070–F-073) and F-081–F-084 are
| F-082 | done | One global configuration path | Hard-removed `Project.androidProjectConfiguration`; `ScriptHandlerScope` form is the single API; `extraPlugins` documented classpath-only; new `PROJECT-CONFIGURATION.md` + cross-links; builds green |
| F-083 | done | One project-global external-deps convention | **House style = `projectDependencies` → `libs.*`**. Typed `build-dependencies/` catalogs = advanced/sample-scale only (not dual happy path). `DEPS-CATALOG.md` + README/GETTING-STARTED/agent skill/08 README |
| F-084 | done | Fleet tooling for explicit graphs (check / generate / migrate) | **v1 in `tools.forma.core.fleet`:** `LayoutChecker` / `LayoutGenerator` / `MigratePlanner` / path forms; `docs/FLEET-TOOLING.md` + agent skill; GH **#54** package→dir covered. Follow-ups: Gradle tasks, AST migrate, depgen — listed in FLEET-TOOLING.md |
| 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 |
| F-085 | done | Full-tree principle audit: sample + examples + agent skills | `docs/PRINCIPLE-AUDIT.md`; teaching stragglers fixed (removed-not-deprecated chain wording); zero live chain/`androidLibrary`/dual-path happy paths |

## Backlog (lower priority / historical GitHub)

Expand Down
2 changes: 1 addition & 1 deletion docs/CALL-SITE-SURFACE.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,4 +92,4 @@ parameters beside them.
- Plugins: [TARGET-PLUGINS.md](TARGET-PLUGINS.md)
- Global config (one path + store story): [`PROJECT-CONFIGURATION.md`](PROJECT-CONFIGURATION.md) (F-082)
- External deps house style: [`DEPS-CATALOG.md`](DEPS-CATALOG.md) (**F-083** — `projectDependencies` happy path; typed catalogs advanced)
- Full-tree teaching audit: **F-085**
- Full-tree teaching audit: [`PRINCIPLE-AUDIT.md`](PRINCIPLE-AUDIT.md) (**F-085**)
124 changes: 124 additions & 0 deletions docs/PRINCIPLE-AUDIT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
# Principle audit (F-085)

Full-tree check that **sample**, **progressive examples**, **agent skills**, and
**teaching docs** match Forma root principles after P7–P8 landed.

| Field | Value |
|-------|--------|
| Date | **2026-07-21** |
| Tip audited | `origin/v2` @ `36d52ba` (+ this F-085 docs slice) |
| Principles | [`VISION.md`](VISION.md) § Root principles |
| Prior tickets | F-070–F-073, F-080–F-084, F-019/F-086 |

## Pass criteria

1. **Bazel-like rules** — type owns behavior; call sites = attributes only.
2. **One global way** — no dual happy paths taught as equals.
3. **Explicit structure + tooling** — matrix + fleet docs present; no generic buckets.

Hard rejects (live code or taught as current):

- `.withPlugin` / `.withPlugins` / `TargetBuilder` / `PluginWrapper`
- Free-form `plugins = plugins(plugin("id"))` on targets
- Restored `androidLibrary`
- `Project.androidProjectConfiguration` dual path
- Equal peer teaching of typed `build-dependencies/` vs `projectDependencies`

## Surfaces scanned

| Surface | Path | Result |
|---------|------|--------|
| Gold sample call sites | `application/**/build.gradle.kts` | **PASS** |
| Sample root config | `application/build.gradle.kts` | **PASS** — `buildscript` + `extraPlugins` classpath only |
| Navigation | `application/core/navigation/res` | **PASS** — Path B `navigationRes` |
| Progressive Android | `examples/android/01`…`10` | **PASS** (wording fix in 10) |
| Progressive JVM | `examples/jvm/01`…`05` | **PASS** |
| Agent skills | `examples/agent-skills/*` | **PASS** (overview/compose/README tightened) |
| User docs | `docs/*`, root `README.md` | **PASS** (VISION sequencing + cross-links) |
| Plugin sources | `plugins/**` | **PASS** — no `TargetBuilder` / `PluginWrapper` types |

## Checklist by principle

### 1. Bazel-like rules / call-site surface

| Check | Status | Evidence |
|-------|--------|----------|
| All Android/JVM target DSLs return `Unit` | PASS | [`CALL-SITE-SURFACE.md`](CALL-SITE-SURFACE.md) |
| Zero live `.withPlugin` call sites | PASS | `rg` on `application`/`examples`/`plugins` (only anti-example comments + TestKit) |
| Type-owned external plugins taught | PASS | step 10, `forma-target-plugins`, sample `navigationRes` |
| `extraPlugins` = classpath only | PASS | sample + example 10 + PROJECT-CONFIGURATION |

### 2. One global way

| Check | Status | Evidence |
|-------|--------|----------|
| Single `androidProjectConfiguration` path | PASS | F-082; `ScriptHandlerScope` only |
| House-style external deps | PASS | DEPS-CATALOG §1; example 08; `forma-deps-catalog` |
| Typed catalogs framed advanced | PASS | DEPS-CATALOG §2; sample may use at monorepo scale |
| No dual “or use either” happy paths | PASS | no equal-peer language in skills/examples |

### 3. Explicit structure + tooling

| Check | Status | Evidence |
|-------|--------|----------|
| `androidLibrary` removed / not taught live | PASS | F-063; deprecation doc is historical |
| Closed matrix documented | PASS | DEPENDENCY-MATRIX + agent skill |
| Fleet check/generate/migrate | PASS | FLEET-TOOLING + `forma-fleet-tooling` |
| Flat role-typed sample graph | PASS | SAMPLE-APP + application layout |

## Findings and fixes (this ticket)

| ID | Severity | Location | Issue | Resolution |
|----|----------|----------|-------|------------|
| A1 | Teaching | `examples/android/10-target-plugins/README.md` | Chain API labeled “(deprecated)” after F-081 hard-remove | **Fixed** → “**removed** F-081”; Next/docs links updated |
| A2 | Teaching | `docs/VISION.md` sequencing § | Still said “deprecate chain withPlugin” | **Fixed** → removed (P7 + F-081); P8 points at this audit |
| A3 | Teaching | `docs/TARGET-PLUGINS.md` F-072 row | “deprecate TargetBuilder” stale vs F-081 | **Fixed** → hard-deprecate then F-081 remove |
| A4 | Completeness | `examples/agent-skills/forma-overview.md` | Ladder stopped at 09; missing P8 docs | **Fixed** → 01…10 + CALL-SITE / PROJECT-CONFIGURATION / FLEET / PRINCIPLE-AUDIT |
| A5 | Completeness | `examples/agent-skills/README.md` | Hard rules omitted plugins/deps/call-site | **Fixed** → rules 6–8 |
| A6 | Teaching | `examples/agent-skills/forma-compose.md` | Implied sample typed catalogs as peer | **Fixed** → house-style note + composeWidget preference |
| A7 | Index | README / PROGRESSIVE-EXAMPLES / CALL-SITE-SURFACE | No audit pointer | **Fixed** — links to this doc |

## Explicit non-issues

| Item | Why OK |
|------|--------|
| Includer TestKit `runner.withPluginClasspath()` | Gradle TestKit API, not Forma chain DSL |
| TARGET-PLUGINS anti-examples showing `.withPlugin` | Clearly “wrong / removed” |
| ANDROID-LIBRARY-DEPRECATION.md | Historical migration guide |
| Sample `build-dependencies/` typed catalogs | Advanced monorepo scale (F-083); not dual default |
| Progressive steps 01–07 bare GAV in `deps("…")` | Teaching ladder before step 08; skills say prefer catalogs in real apps |
| Sample Firebase/Crashlytics classpath without derived `firebaseBinary` yet | Comment documents Path B intent; not a live `.withPlugins` chain |
| PROGRESS.md historical “deprecate” language | Chronological log; not user teaching |

## Residual / out of scope

Not opened as new product tickets here (board empty after F-085; promote only on request):

- Mass-migrate sample modules from typed catalogs → `projectDependencies` (F-083 intentionally out of scope)
- Optional Path B `firebaseBinary` for Crashlytics/GMS apply (sample currently classpath + comment)
- F-084 follow-ups (Gradle tasks, AST migrate) — listed in FLEET-TOOLING.md
- F-019 AndroidX absolute ceiling / compileSdk chase
- Legacy `.kapt` API removal once no consumers
- Backlog GH issues (#110, #97, #88, #82, …)

## Re-audit recipe

```bash
# Live anti-patterns (expect empty for production Forma DSL)
rg -n '\.withPlugin|\.withPlugins|TargetBuilder|PluginWrapper' \
plugins application examples jvm-application build-dependencies \
-g '*.kt' -g '*.kts'

rg -n '\bandroidLibrary\s*\(' -g '*.kts' -g '*.kt' application examples plugins
rg -n 'plugins\s*=\s*plugins\s*\(' -g '*.kts' application examples

# Teaching: chain must be "removed", not live "deprecated" happy path
rg -n 'withPlugin.*deprecat|chains \(deprecated\)' examples docs README.md
```

## Related

- [`CALL-SITE-SURFACE.md`](CALL-SITE-SURFACE.md) · [`TARGET-PLUGINS.md`](TARGET-PLUGINS.md)
- [`PROJECT-CONFIGURATION.md`](PROJECT-CONFIGURATION.md) · [`DEPS-CATALOG.md`](DEPS-CATALOG.md)
- [`FLEET-TOOLING.md`](FLEET-TOOLING.md) · [`PROGRESSIVE-EXAMPLES.md`](PROGRESSIVE-EXAMPLES.md)
- Board: `TICKETS.md` P8
20 changes: 20 additions & 0 deletions docs/PROGRESS.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,26 @@

Newest entries first.

## 2026-07-21 — F-085: full-tree principle audit

- **Ticket:** F-085 → `done`
- **Branch:** `forma/F-085-principle-audit` (from origin/v2 @ `36d52ba`)
- **Skills/modes:** Grok Build `--mode full` design **503** + implement **timeout** (no tree changes); Hermes finish path for docs/teaching audit (F-085 class)
- **Audit record:** new `docs/PRINCIPLE-AUDIT.md` (checklist, findings A1–A7, non-issues, re-audit recipe)
- **Live code:** zero production `.withPlugin` / `TargetBuilder` / `PluginWrapper` / `androidLibrary` / free-form `plugins=` — sample uses Path B `navigationRes`; root config is single `buildscript` path
- **Teaching fixes:**
- `examples/android/10-target-plugins/README.md` — chain API **removed** (was “deprecated”); audit/CALL-SITE links
- `docs/VISION.md` sequencing — P6–P8 marked complete; withPlugin **removed**
- `docs/TARGET-PLUGINS.md` F-072 row notes F-081 hard-remove
- Agent skills: `forma-overview` (ladder 01…10 + P8 docs), hard rules 6–8, `forma-compose` house-style note
- Cross-links: README, PROGRESSIVE-EXAMPLES, CALL-SITE-SURFACE
- **Out of scope (documented):** sample mass-migrate off typed catalogs; optional `firebaseBinary`; F-084 Gradle-task follow-ups; AndroidX ceiling
- **Verify (real host, `source scripts/env-mac.sh`):**
- `plugins/ ./gradlew build` → **BUILD SUCCESSFUL** (78 tasks)
- `application/ ./gradlew build` → **BUILD SUCCESSFUL** (2322 tasks)
- **Blockers:** none
- **Next:** P8 complete — empty product board; promote backlog only on user request

## 2026-07-20 — F-084: fleet tooling check/generate/migrate v1

- **Ticket:** F-084 → `done` (v1 toolkit; follow-ups listed in `docs/FLEET-TOOLING.md`)
Expand Down
8 changes: 8 additions & 0 deletions docs/PROGRESSIVE-EXAMPLES.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,15 @@ narrative tutorials when you want a **minimal buildable project per concept**.

See [examples/README.md](../examples/README.md).

## Principle alignment

Teaching ladder + agent skills were audited against root principles in
[PRINCIPLE-AUDIT.md](PRINCIPLE-AUDIT.md) (F-085). Do not reintroduce chain APIs,
dual happy paths, or removed `androidLibrary` into examples or skills.

## Relationship to gold standards

Progressive examples are **minimal**. Patterns for real apps (navigation, Dagger,
network) live in `application/` and are documented in SAMPLE-APP / GETTING-STARTED.
Sample-scale typed `build-dependencies/` catalogs are **advanced**, not a second
default (see [DEPS-CATALOG.md](DEPS-CATALOG.md)).
2 changes: 1 addition & 1 deletion docs/TARGET-PLUGINS.md
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,7 @@ firebaseBinary(
|----|--------|------------|
| **F-070** | This design | Merged on `v2` |
| **F-071** | `targetPlugin`, type→plugin registry, auto-apply in pre-defined DSLs (Path A lookup), `deriveTargetType` core hooks | unit tests: type with plugin applies without call-site API; plugins build green |
| **F-072** | Path B DSL helpers; migrate sample navigation (+ optional firebase binary type); deprecate `TargetBuilder` / `PluginWrapper` | application green; **zero** `.withPlugin` call sites; call sites Bazel-flat |
| **F-072** | Path B DSL helpers; migrate sample navigation (+ optional firebase binary type); hard-deprecate then **F-081 remove** `TargetBuilder` / `PluginWrapper` | application green; **zero** `.withPlugin` call sites; call sites Bazel-flat |
| **F-073** | Docs + progressive example + agent skill; close GH #36 | **done** — `docs/TARGET-PLUGINS.md` how-to, `examples/android/10-target-plugins`, `forma-target-plugins` skill |

---
Expand Down
6 changes: 3 additions & 3 deletions docs/VISION.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,9 @@ Concrete stacks built **on** forma-core:
2. **Extract forma-core** — peel framework concerns out of the Android plugin while Android keeps working.
3. **JVM implementation** — prove core is portable.
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+).
5. **Flat-structure hardening** — remove generic targets that undermine role typing (P6 / F-060–F-063; `androidLibrary` gone).
6. **Uniform target plugins** — Bazel-like: plugin on the **target type**, auto-apply on every call site; call sites are attributes-only; chain `withPlugin` **removed** (P7 / F-070–F-073 + F-081; [`TARGET-PLUGINS.md`](TARGET-PLUGINS.md)).
7. **Principle-alignment implementation** — close remaining gaps vs root principles (P8 / F-080–F-085; audit: [`PRINCIPLE-AUDIT.md`](PRINCIPLE-AUDIT.md)).

## Working principles

Expand Down
3 changes: 3 additions & 0 deletions examples/agent-skills/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,6 @@ matrix rules, and progressive example pointers.
3. Suffix of project name must match DSL (`…/impl` → `impl { }`)
4. `packageName` must match source root path
5. Do not weaken validators to “make it build”
6. No `.withPlugin` / free-form plugin id lists / restored `androidLibrary`
7. One global way per concern — house-style deps = `projectDependencies` → `libs.*`; type owns plugins
8. Call sites = attributes only (`docs/CALL-SITE-SURFACE.md`); see `docs/PRINCIPLE-AUDIT.md`
5 changes: 4 additions & 1 deletion examples/agent-skills/forma-compose.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,7 @@ androidBinary(..., compose = true, ...)
- Forma enables `buildFeatures.compose` + compiler extension version
- **You** still add Compose Maven artifacts
- Align compiler version with Kotlin (sample: 2.3.21 ↔ 2.3.21)
- **`deps("gav")` is non-transitive** — use `transitiveDeps(...)` for Compose (same as `androidx.compose` in `build-dependencies/`)
- **`deps("gav")` is non-transitive** — use `transitiveDeps(...)` for Compose
- Tiny ladder steps may inline GAV strings; real apps use house-style
`projectDependencies` → `libs.*` ([DEPS-CATALOG.md](../../docs/DEPS-CATALOG.md)).
Prefer `composeWidget` when the module is Compose-only UI (type owns Compose on).
23 changes: 16 additions & 7 deletions examples/agent-skills/forma-overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,25 +14,34 @@ shared configuration, and a **dependency restriction graph**.

| Plugin id | Module | Sample | Progressive ladder |
|-----------|--------|--------|--------------------|
| `tools.forma.android` | `plugins/android` | `application/` | `examples/android/01`…`09` |
| `tools.forma.android` | `plugins/android` | `application/` | `examples/android/01`…`10` |
| `tools.forma.jvm` | `plugins/jvm` | `jvm-application/` | `examples/jvm/01`…`05` |
| `tools.forma:core` | `plugins/core` | — | restriction engine |
| `tools.forma:core` | `plugins/core` | — | restriction engine + fleet toolkit |
| Bazel adapter | `bazel-adapter/` | `bazel-sample/` | skill `forma-bazel` |

## Learning order for agents

1. This overview + `forma-includer-settings` + `forma-project-layout`
2. Platform targets (`forma-android-targets` or `forma-jvm-targets`)
3. `forma-dependency-matrix` before multi-module wiring
4. `forma-deps-catalog` / `forma-compose` as needed
5. Walk progressive examples in order; copy the **smallest** step that has the feature
4. `forma-deps-catalog` (house style) / `forma-compose` as needed
5. `forma-target-plugins` before any third-party Gradle plugin
6. `forma-fleet-tooling` when scaffolding/renaming packages at scale
7. Walk progressive examples in order; copy the **smallest** step that has the feature

## Docs of record

- `docs/VISION.md` — root principles
- `docs/DEPENDENCY-MATRIX.md` — live validator truth (Android)
- `docs/JVM-TARGETS.md` — JVM matrix
- `docs/GETTING-STARTED.md` / `docs/JVM-GETTING-STARTED.md`
- `docs/PROGRESSIVE-EXAMPLES.md`
- `docs/COMPOSE.md`, `docs/DEPS-CATALOG.md`

- **External plugins:** type-owned (Path A/B) — skill `forma-target-plugins`, docs `TARGET-PLUGINS.md`, example `android/10-target-plugins`.
- `docs/CALL-SITE-SURFACE.md` — Unit DSLs, flags, removed chain API
- `docs/PROJECT-CONFIGURATION.md` — single `androidProjectConfiguration` path
- `docs/DEPS-CATALOG.md` — house style `projectDependencies`
- `docs/TARGET-PLUGINS.md` — type-owned plugins (Path A/B)
- `docs/FLEET-TOOLING.md` — check/generate/migrate
- `docs/COMPOSE.md`
- `docs/PRINCIPLE-AUDIT.md` — full-tree teaching audit (F-085)

**External plugins:** type-owned (Path A/B) — skill `forma-target-plugins`, example `android/10-target-plugins`. Never `.withPlugin`.
Loading
Loading