From 60d073a0402e162582b9091c8a3cb68b3d67b3bd Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 30 Apr 2026 08:19:03 +0000 Subject: [PATCH 1/3] chore: open auto-fix batch claude/friendly-maxwell-cVhhm From c9f1ba63c8f225c891250eb6681ea9b7a8588c0a Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 30 Apr 2026 08:28:16 +0000 Subject: [PATCH 2/3] fix(web): drop redundant as u32 casts on js_sys Date::get_month + add wasm clippy CI gate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit caveman go: get_month already u32 on wasm32. cast bad. clippy yell. fix yell. three sites swept in crates/web/src/components/message_row/day_separator.rs: - ts_m: drop `as u32` - now_m: drop `as u32` - y_m: drop `as u32` comment block above also tweaked to reflect that cast is no longer the NaN-collapse vector for `get_month` / `get_date` (it's the implicit u32 return that does the collapsing now); behaviour identical, doc just true. CI guard wired per issue Option 1 (no extra job, just a step in the existing wasm job). add `components: clippy` to the toolchain action + new step `cargo clippy --target wasm32-unknown-unknown -p willow-web --all-targets -- -D warnings` after the existing wasm cargo check. won't hit the wasm-streams duplicate-symbol blocker that reverted PR #498's CI guard: clippy is check-style, never links the wasm binary, so the duplicate-symbol link error can't fire here. verified locally — `cargo clippy --target wasm32-unknown-unknown -p willow-web --all-targets -- -D warnings` finishes clean, zero warnings. Refs #497 --- .github/workflows/ci.yml | 3 +++ .../web/src/components/message_row/day_separator.rs | 11 ++++++----- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 22b3c2fd..45893c93 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -110,6 +110,7 @@ jobs: - uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable with: targets: wasm32-unknown-unknown + components: clippy - uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 with: path: | @@ -119,6 +120,8 @@ jobs: key: wasm-${{ hashFiles('**/Cargo.lock') }} restore-keys: wasm- - run: cargo check --target wasm32-unknown-unknown --workspace --exclude willow-relay --exclude willow-worker --exclude willow-replay --exclude willow-storage --exclude willow-agent + - name: Clippy (wasm32, willow-web) + run: cargo clippy --target wasm32-unknown-unknown -p willow-web --all-targets -- -D warnings browser: name: Browser tests (wasm-pack + Firefox) diff --git a/crates/web/src/components/message_row/day_separator.rs b/crates/web/src/components/message_row/day_separator.rs index 2c0dcb80..2547680f 100644 --- a/crates/web/src/components/message_row/day_separator.rs +++ b/crates/web/src/components/message_row/day_separator.rs @@ -111,8 +111,9 @@ pub fn day_bucket(ts_ms: u64) -> DayBucket { use wasm_bindgen::JsValue; // Out-of-range timestamps make `js_sys::Date` accessors return NaN; - // the `as i32` / `as u32` casts then collapse to 0, which would index - // into `WEEKDAYS`/`MONTHS` and produce a bogus "sunday · 0 january" + // the `as i32` cast (and the implicit `u32` return on `get_month` / + // `get_date`) then collapse to 0, which would index into + // `WEEKDAYS`/`MONTHS` and produce a bogus "sunday · 0 january" // label. Bail to a stable fallback variant instead. if ts_ms > MAX_VALID_TS_MS as u64 { return DayBucket::Older { @@ -127,11 +128,11 @@ pub fn day_bucket(ts_ms: u64) -> DayBucket { let now = js_sys::Date::new_0(); let ts_y = ts.get_full_year() as i32; - let ts_m = ts.get_month() as u32; + let ts_m = ts.get_month(); let ts_d = ts.get_date(); let now_y = now.get_full_year() as i32; - let now_m = now.get_month() as u32; + let now_m = now.get_month(); let now_d = now.get_date(); if (ts_y, ts_m, ts_d) == (now_y, now_m, now_d) { @@ -152,7 +153,7 @@ pub fn day_bucket(ts_ms: u64) -> DayBucket { 0, ); let y_y = yesterday.get_full_year() as i32; - let y_m = yesterday.get_month() as u32; + let y_m = yesterday.get_month(); let y_d = yesterday.get_date(); if (ts_y, ts_m, ts_d) == (y_y, y_m, y_d) { return DayBucket::Yesterday; From da21fedd54a531b34fae6610977c15614ac8c8ef Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 30 Apr 2026 08:30:08 +0000 Subject: [PATCH 3/3] docs(skill): add coordinator-direct already-fixed sweep before dispatch Run on `claude/friendly-maxwell-cVhhm` showed 6 of 7 picked issues were already-fixed-upstream (#465 by skill rewrite eliminating sub-PRs, #426 #438 #477 #493 by 8d91a11 folding lessons into general-audit, #429 by 1a9503f LRU+TTL on ProfileState/typing_peers). Dispatching implementers for no-op close-with-comment work wastes cycles. Promote already-fixed sweep to coordinator-direct first pass, BEFORE any implementer dispatch. Closing GH issues = metadata work, not code work, allowed under "coordinator never codes." Implementers only dispatch for unresolved issues. Renumber subsequent Core Loop steps (7-10). --- .claude/skills/resolving-issues/SKILL.md | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/.claude/skills/resolving-issues/SKILL.md b/.claude/skills/resolving-issues/SKILL.md index a6d16629..035fdd70 100644 --- a/.claude/skills/resolving-issues/SKILL.md +++ b/.claude/skills/resolving-issues/SKILL.md @@ -47,7 +47,18 @@ Why this shape: 3. Skip big features + major refactors. Out of scope. 4. No in-scope issues? Noop. Skip the rest. No master branch created, no PR opened. 5. Create fresh master branch (see ## Master Branch Setup). -6. Per issue, sequential, max 10 per run: +6. **Coordinator-direct already-fixed sweep (run BEFORE any implementer dispatch).** For each picked issue, before dispatching, scan recent merged commits + closing PRs against the issue's scope: + - `git log --oneline ..origin/main -- ` to find candidate fix commits + - `mcp__github__search_pull_requests` w/ issue keywords for closure-by-PR cases + - cross-check against recent general-audit master tickets ("verified fixed by ..." entries) + + If the issue is resolved by a landed change, do the close pass directly — no implementer dispatch: + - caveman comment on the issue citing the upstream commit / PR + the fix location + - close `completed` (audit intent now holds) or `not_planned` (audit premise moot) + - record under `## Already-Fixed` for master PR body + + Closing GH issues = metadata work, not code work; allowed under "coordinator never codes." Implementers only dispatch for *unresolved* issues. This pass typically clears audit lessons (already folded into skills), structural-deps follow-ups (still structural), and audit findings closed by intervening fixes — saves dispatch overhead on no-op work. +7. Per remaining issue, sequential, max 10 per run: - **Pre-dispatch sync:** before spawning each implementer, in the coordinator's checkout: ```bash git fetch origin @@ -56,11 +67,11 @@ Why this shape: Prior implementers' commits must be the implementer's base; stale local state poisons the next dispatch. - Spawn fresh implementer agent (see ## Implementer Agent below). - Implementer commits directly to master branch and pushes. No worktree, no sub-PR. - - Track `Fixes #N` for final PR body assembly. **Already-fixed-upstream** issues go under `## Already-Fixed`, not `Fixes`. + - Track `Fixes #N` for final PR body assembly. - Next issue. -7. Implementer finds related rot? File follow-up issue. -8. Apply Lessons Learned skill edits to `.claude/skills/resolving-issues/SKILL.md`, commit on master branch, push. (Coordinator does this directly — see ### Coordinator never codes.) -9. Open the master PR — **ready (not draft)** — base `main`, head master branch. Body: `Fixes #N` list + `## Already-Fixed` + `## Parked` + `## Skill Evolution` + `## Lessons Learned`. Master PR runs full CI; human merges when satisfied. If anything's unfinished, leave the branch un-PR'd instead of opening a draft. +8. Implementer finds related rot? File follow-up issue. +9. Apply Lessons Learned skill edits to `.claude/skills/resolving-issues/SKILL.md`, commit on master branch, push. (Coordinator does this directly — see ### Coordinator never codes.) +10. Open the master PR — **ready (not draft)** — base `main`, head master branch. Body: `Fixes #N` list + `## Already-Fixed` + `## Parked` + `## Skill Evolution` + `## Lessons Learned`. Master PR runs full CI; human merges when satisfied. If anything's unfinished, leave the branch un-PR'd instead of opening a draft. ## Implementer Agent