Skip to content

feat(compose-agent): cross-phase back-write + false-lead authoring guidance (4.3.1)#11

Open
hamen wants to merge 4 commits into
mainfrom
feat/compose-agent-cross-phase-4.3.1
Open

feat(compose-agent): cross-phase back-write + false-lead authoring guidance (4.3.1)#11
hamen wants to merge 4 commits into
mainfrom
feat/compose-agent-cross-phase-4.3.1

Conversation

@hamen

@hamen hamen commented Jul 6, 2026

Copy link
Copy Markdown
Owner

What

Follow-up to #10 / v4.3.0. That release taught jetpack-compose-audit to catch cross-phase back-writes and no-op "recomposition fixes". This teaches compose-agent (the authoring skill) to avoid writing them — closing the drift the round-3 reviewers flagged. It also ships a suite-wide Strong Skipping correctness fix.

Changes

File Change
compose-agent/references/performance.md Never Back-Write Across Phases (cross-phase + composition-phase self-invalidation, good/bad Kotlin), Optimizations That Do Nothing, aligned Lambdas In Composables section, extended grep triggers
compose-agent/SKILL.md Core Instruction, review-checklist line, Review Process step 4
jetpack-compose-audit/references/scoring.md Strong Skipping fix: removed the "unless the lambda captures an unstable value" carve-out (SSM memoizes lambdas even with unstable captures) — 4 spots
versions compose-agent4.3.1, jetpack-compose-audit4.3.1
CHANGELOG.md, README.md, docs/release-notes-4.3.1.md 4.3.1 notes

Why the audit bump

The 4.3.0 false-lead guard still allowed manual callback remember "when the lambda captures an unstable value." Per the official Strong Skipping docs that is wrong — SSM wraps lambdas in remember even with unstable captures — so the carve-out could bless the exact no-op the guard forbids. Removed suite-wide; only SSM-off / @DontMemoize / @NonSkippableComposable remain.

Validation

bin/ci ✅. Continues the chrisbanes/skills (Apache-2.0) adaptation.

🤖 Generated with Claude Code

https://claude.ai/code/session_016ysskXsKpwEbs1n9CX1ScY

…idance (4.3.1)

Follow-up to 4.3.0. The audit catches cross-phase back-writes and no-op
"recomposition fixes" after the fact; compose-agent now warns while the code is
being written, closing the drift the 4.3.0 cross-review flagged.

- performance.md: "Never Back-Write Across Phases" (layout->composition writes;
  snapshot-collection mutation in a @composable body, good/bad Kotlin) and
  "Optimizations That Do Nothing" (remember(index) on pure fns, remember-ing an
  auto-memoized callback under SSM, identity caches, hoisting without stabilizing
  captures). Grep triggers extended.
- SKILL.md: Core Instruction, review-checklist line, Review Process step 4.
- Versions: compose-agent -> 4.3.1; jetpack-compose-audit unchanged at 4.3.0.
- evals description updated: compose-agent now covers the topic.

Continues the chrisbanes/skills (Apache-2.0) adaptation, cited against
developer.android.com.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016ysskXsKpwEbs1n9CX1ScY
@hamen

hamen commented Jul 6, 2026

Copy link
Copy Markdown
Owner Author
🟠 Antigravity review (automated cross-review)

LGTM. The PR correctly updates the compose-agent authoring guidelines to mirror the 4.3.0 audit rules for cross-phase back-writes and false-lead optimizations, with solid Kotlin examples and a safe description fix in evals.json.

via pr-review-relay · author: claude

hamen and others added 3 commits July 6, 2026 18:39
…, example

Round-1 cross-review (Codex, Cursor; Antigravity LGTM) — no blockers:

- SSM correctness (Codex + Cursor, the big one): removed the "...unless the
  lambda captures an unstable value" carve-out from BOTH skills. Per the official
  Strong Skipping docs, SSM memoizes lambdas even with unstable captures, so that
  exception could still bless the no-op the guard forbids. Fixed compose-agent
  performance.md + all four spots in jetpack-compose-audit scoring.md. Only
  remaining exception: SSM-off or @DontMemoize / @NonSkippableComposable.
  -> jetpack-compose-audit bumped to 4.3.1 (correctness patch).
- Terminology (Cursor): compose-agent now labels snapshot-collection mutation as
  composition-phase self-invalidation, not cross-phase, in the section, the
  Core Instruction, and the example header.
- Example fix (Cursor): the layout good/bad example now uses label AND value on
  both sides (value was orphaned before).
- Grep-trigger parity: added addAll/remove/-= and SnapshotStateList/Map.
- Stale note in release-notes-4.3.0.md updated (addressed in 4.3.1).
- README top-summary no longer reads as a version conflict.

Versions: compose-agent -> 4.3.1, jetpack-compose-audit -> 4.3.1.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016ysskXsKpwEbs1n9CX1ScY
…mbdas section

Round-2 cross-review (Codex, Cursor) — addresses both blockers:

- BLOCKER: the "Bad" cross-phase example used Modifier.offset { } — a layout-phase
  (deferred) read, i.e. the safe pattern, not a composition read. Switched to the
  non-lambda Modifier.offset(x = labelWidth.toDp()) so it actually reads in
  composition and demonstrates the layout->composition loop (matches eval 12).
- BLOCKER: the pre-existing "Lambdas In Composables" section still claimed manual
  remember matters for cross-module/generic composables under SSM. Aligned to the
  official docs + the false-lead guard: SSM wraps all lambdas (even unstable
  captures); only SSM-off / @DontMemoize / @NonSkippableComposable remain.
- README hero line bumped to jetpack-compose-audit 4.3.1 (was stale at 4.3.0).
- Core Instruction: self-invalidation is mutate->recompose, not measure-driven.
- PR description updated to reflect the audit 4.3.1 bump.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016ysskXsKpwEbs1n9CX1ScY
…DME/notes

Round-3 cross-review (Codex blocker + Cursor) — final pass:

- BLOCKER: the Strong Skipping *baseline* list (top of performance.md) still said
  captured lambdas can churn via "opaque call sites / generics". Rewrote item 2:
  SSM memoizes every lambda passed to a composable (even unstable captures), so
  lambdas are not a skipping defeater; manual remember only matters SSM-off /
  @DontMemoize. Removed the obsolete cross-module bullet (memoization is at the
  caller's compilation regardless of callee module/generics) and documented why.
- Example now compiles: gap computed in MeasureScope (a Density), not in the
  PlacementScope where dp.roundToPx() has no receiver.
- "all lambdas" tightened to "every lambda passed to a composable".
- README authoring-mode checklist gains step 8 (cross-phase / self-invalidation).
- Core Instruction split into two bullets (cross-phase vs no-op optimizations).
- release-notes-4.3.0 false-lead bullet marked corrected-in-4.3.1.
- release-notes-4.3.1: documented the cross-module removal + eval coverage note.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016ysskXsKpwEbs1n9CX1ScY
@hamen

hamen commented Jul 6, 2026

Copy link
Copy Markdown
Owner Author
🟢 Codex review (automated cross-review)

Blocker

  • performance.md, scoring.md, evals.json: the PR still treats @NonSkippableComposable as a remaining exception where manual callback remember “matters.” Per the official Strong Skipping docs, @NonSkippableComposable opts a composable out of skipping; lambda memoization remains a separate Strong Skipping behavior, with @DontMemoize as the lambda opt-out. This leaves the same false-lead class alive in authoring guidance, audit scoring, and the acceptance eval. Remove @NonSkippableComposable from the callback-memoization exception wording; keep it only in skippability/opt-out justification rules.

Should-fix

  • None.

Nit

  • None.

Validation: read gh pr view 11, gh pr diff 11, all touched files, related audit playbook/scoring context, and the current Android Strong Skipping docs: https://developer.android.com/develop/ui/compose/performance/stability/strongskipping. git diff --check origin/main...HEAD is clean.

via pr-review-relay · author: claude

@hamen

hamen commented Jul 6, 2026

Copy link
Copy Markdown
Owner Author
🔵 Cursor review (automated cross-review)

PR #11 review — feat(compose-agent): cross-phase back-write + false-lead authoring guidance (4.3.1)

Solid follow-up to 4.3.0: it closes audit/authoring drift, the Strong Skipping “unstable capture” fix matches official SSM docs, and cross-phase guidance aligns with search-playbook.md / evals 12–14. No security issues (docs-only).


Blocker

None.


Should-fix

  1. @NonSkippableComposable bundled with @DontMemoize as a lambda-memoization exception — In performance.md, scoring.md (4 places), and eval 13, manual callback remember is still said to matter on @NonSkippableComposable / @DontMemoize paths. Per the SSM docs, @NonSkippableComposable opts the composable out of skipping; @DontMemoize opts a lambda out of memoization. SSM still auto-memoizes lambdas inside a @NonSkippableComposable body. Keeping @NonSkippableComposable in this exception list can still bless unnecessary remember on hot paths. Drop it from the callback-memoization exceptions; keep it only in skippability / opt-out justification rules.

  2. Missing layout-only-read nuance in compose-agentsearch-playbook.md allows onSizeChanged → state when that state is consumed only in layout/draw (e.g. Modifier.layout { }), and flags only composition-phase reads. performance.md scopes the bad pattern correctly in the detailed bullet, but never states that exception, so agents may over-prescribe custom Layout where a layout-phase read would suffice. One sentence mirroring the audit heuristic would align authoring with scoring.

  3. No compose-agent write-mode evals — Evals 12–14 remain audit-shaped; evals.json description was updated but nothing exercises compose-agent while writing code. Drift risk is lower than pre-4.3.1, but the release notes already track this as follow-up — worth doing before the next authoring change.


Nit

  1. SKILL.md References blurbreferences/performance.md still lists “stability, Strong Skipping, lambda modifiers…” but not cross-phase back-writes / false leads; minor discoverability gap.

  2. Long Core Instruction bullet — One dense bullet covers cross-phase back-writes, self-invalidation, and false leads; splitting to match performance.md would help agent parsing.

  3. SSM lambda scope wording — “Every lambda passed to a composable” is fine for the false-lead case; official docs say “every lambda inside a composable function,” which is slightly broader. Optional tighten for precision.

  4. Layout good example8.dp.roundToPx() is fine: MeasureScope is a Density receiver. No change needed (contrary to an earlier automated review).

  5. docs/release-notes-4.3.0.md — Already carries a historical correction on the unstable-capture bullet (line 27). No further edit required.


Summary: Correct direction, good suite alignment, versioning/docs consistent. Before merge, I'd fix the @NonSkippableComposable / @DontMemoize conflation (#1) and optionally add the layout-only-read exception (#2).

via pr-review-relay · author: claude

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant