From ae0f8781703f016dded8ba67d997c477f10c7449 Mon Sep 17 00:00:00 2001 From: CesarNML Date: Wed, 17 Jun 2026 10:55:30 +0700 Subject: [PATCH 1/5] feat(runes): migrate Navbar cluster to Svelte 5 runes [P6.06] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `$: dropdownUrls/navUrls` → `$derived`, `$: if (media.sm)` → `$effect`, `export let` → `$props()`, `` → `{@render children?.()}`, `on:click` → `onclick`, legacy svelte-ignore directives updated to underscore form; store auto-subscriptions kept as-is (runes-valid). --- src/lib/components/Navbar/NavDropdown.svelte | 4 +++- src/lib/components/Navbar/NavEnd.svelte | 2 ++ src/lib/components/Navbar/NavLink.svelte | 8 ++++---- src/lib/components/Navbar/NavLinks.svelte | 10 ++++++---- src/lib/components/Navbar/NavLogo.svelte | 9 +++++++-- src/lib/components/Navbar/NavMenu.svelte | 8 +++++--- src/lib/components/Navbar/Navbar.svelte | 10 +++++++--- 7 files changed, 34 insertions(+), 17 deletions(-) diff --git a/src/lib/components/Navbar/NavDropdown.svelte b/src/lib/components/Navbar/NavDropdown.svelte index 7f48a9e4..f7f0f548 100644 --- a/src/lib/components/Navbar/NavDropdown.svelte +++ b/src/lib/components/Navbar/NavDropdown.svelte @@ -1,3 +1,5 @@ + + {#if $dropdown} diff --git a/src/lib/components/Navbar/NavEnd.svelte b/src/lib/components/Navbar/NavEnd.svelte index 2edfc061..73b31a7d 100644 --- a/src/lib/components/Navbar/NavEnd.svelte +++ b/src/lib/components/Navbar/NavEnd.svelte @@ -1,3 +1,5 @@ + + diff --git a/src/lib/components/Navbar/NavMenu.svelte b/src/lib/components/Navbar/NavMenu.svelte index 22ac12ad..23cd0055 100644 --- a/src/lib/components/Navbar/NavMenu.svelte +++ b/src/lib/components/Navbar/NavMenu.svelte @@ -1,15 +1,17 @@ -
{#if $dropdown} - {:else} - {/if} diff --git a/src/lib/components/Navbar/Navbar.svelte b/src/lib/components/Navbar/Navbar.svelte index 4950d2ad..4ff6c572 100644 --- a/src/lib/components/Navbar/Navbar.svelte +++ b/src/lib/components/Navbar/Navbar.svelte @@ -1,3 +1,5 @@ + +
Date: Wed, 17 Jun 2026 10:58:05 +0700 Subject: [PATCH 2/5] chore(P6.06): record subagent adversarial review prompt --- .../reviews/P6.06-subagent-review.prompt.md | 75 +++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 docs/product/delivery/phase-06/reviews/P6.06-subagent-review.prompt.md diff --git a/docs/product/delivery/phase-06/reviews/P6.06-subagent-review.prompt.md b/docs/product/delivery/phase-06/reviews/P6.06-subagent-review.prompt.md new file mode 100644 index 00000000..1995f674 --- /dev/null +++ b/docs/product/delivery/phase-06/reviews/P6.06-subagent-review.prompt.md @@ -0,0 +1,75 @@ +You are conducting an adversarial review of a code change. +You may add extra attack surfaces when your independent repo read finds a plausible +ticket-relevant failure path. +Findings outside the three finding-discipline clauses belong in **Advisory Observations** — +anything off-scope but real is welcome there. +Your job is not a general code review — it is a targeted attack on the behavior this ticket is supposed to +protect. Start from the invariants and attack surfaces below, then independently inspect +the diff and directly related implementation code for missing ticket-relevant risks. You +are looking for paths where the ticket's intended behavior breaks, not for general +improvements. + +### Ticket scope + +**Outcome:** +- These 7 files use runes only: `Navbar/{Navbar,NavDropdown,NavEnd,NavLink,NavLinks,NavLogo,NavMenu}.svelte`. +- `export let` → `$props()`; `$:` → `$derived`/`$effect`; `NavLogo`'s `` → snippet (consumer ripple owned here). +- `$dropdown`/`$loading`/`$navigating` store auto-subscription is **kept as-is** (valid in runes mode — intentional per the stores-stay deferral). +- Each file carries ``. +- `grep` for legacy idioms in these files returns zero. + +**Review Focus from ticket:** +- `$dropdown`/`$loading`/`$navigating` NOT converted to `$state` — confirm they remain store subscriptions (regressing this breaks the stores-stay deferral). +- Dropdown open/close toggling and `class:dropdownVisible={$dropdown}` reactivity unchanged. +- Smoke: mobile nav dropdown opens/closes; loading/navigating indicator still reacts. + +**Rationale:** +- Red first: n/a (`Red: skip`). +- Why this path: Navbar is a self-contained cluster and the primary consumer of the kept `writable` stores; isolating it makes the "store auto-sub stays" intent reviewable in one diff. +- Alternative considered: converting `$dropdown`/`$loading` to `$state` runes — rejected per product-plan stores-stay deferral. +- Deferred: routes and remaining leaves (T07). + +### Files touched + +Implementation: +- src/lib/components/Navbar/NavDropdown.svelte +- src/lib/components/Navbar/NavEnd.svelte +- src/lib/components/Navbar/NavLink.svelte +- src/lib/components/Navbar/NavLinks.svelte +- src/lib/components/Navbar/NavLogo.svelte +- src/lib/components/Navbar/NavMenu.svelte +- src/lib/components/Navbar/Navbar.svelte + +Tests: +- (none — Red: skip; existing Navbar.spec.ts is the guard) + +### Invariants to hold + +1. All 7 Navbar files have `` and zero legacy idioms (`export let`, `$:`, ``, `on:` event directives, legacy `svelte-ignore` directive format). +2. `$dropdown`, `$loading`, and `$navigating` remain store auto-subscriptions (not `$state`) — the stores-stay deferral must not be silently regressed. +3. `NavLogo`'s slot→snippet conversion (`` → `{@render children?.()}`) is consistent with its consumer usage in `Navbar.svelte` (`` passes children as implicit snippet). + +### Attack surfaces to probe + +- `Navbar.svelte` `$effect` for dropdown close on `$media.sm`: does the effect fire correctly when `$media.sm` transitions from false to true, given that `$effect` tracks reactive reads within its body? (`$media` is a store, and `$media.sm` is a property — verify store subscription works as expected inside `$effect`.) +- `NavLink.svelte` `$props()` destructuring with default: `isLarge = false` default — does the Svelte 5 `$props()` pattern with inline default produce the same runtime behavior as `export let isLarge = false`? Verify the type annotation `isLarge?: boolean` correctly permits the default. +- `NavLogo.svelte` snippet passthrough: `{@render children?.()}` — optional chaining means the button renders empty if no children are passed. The only consumer is `Navbar.svelte` which always passes ``. Confirm there is no call-site where NavLogo is used without children (empty button would be invisible and non-functional). +- `NavLinks.svelte` store-filtered `$derived`: `const navUrls = $derived(TOP_LEVEL_NAV_URLS.filter((url) => url !== Url.Projects || $session))` — `$session` is a store auto-sub inside `$derived`. Confirm Svelte 5 correctly tracks store auto-subscriptions within `$derived` (this is valid but worth asserting). +- Legacy `svelte-ignore` directive migration in `NavLinks.svelte`: old `a11y-label-has-associated-control` → new `a11y_label_has_associated_control` (underscore form). Confirm all three occurrences were updated and no legacy hyphen form remains. +- `NavMenu.svelte` added `lang="ts"` to `