Lucas Berger and Claude Sonnet 4.6
72977334fc
fix(20): CR-01 WR-06 atomic last-admin guard + empty-body 400
...
Wrap the last-admin check and UPDATE in a db.transaction with a
SELECT...FOR UPDATE locking read so concurrent PATCH demotions
serialise and cannot both pass the guard, eliminating the TOCTOU
race (CR-01).
Add a .refine() to updateMemberSchema requiring at least one field,
returning 400 via noEchoHook instead of crashing Drizzle with an
empty SET clause (WR-06).
Add Test H asserting empty {} -> 400 { error: 'Invalid request' }.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-18 17:59:56 -04:00
Lucas Berger
5c74ada48b
docs(20): add deep code review report
2026-06-18 17:57:08 -04:00
Lucas Berger and Claude Opus 4.8
f656a0c77b
docs(phase-20): evolve PROJECT.md after phase completion
...
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com >
2026-06-18 17:48:23 -04:00
Lucas Berger and Claude Opus 4.8
dec8220da3
docs(phase-20): complete phase execution — verification passed (9/9), advisory review
...
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com >
2026-06-18 17:47:51 -04:00
Lucas Berger
80fd683877
docs(20-03): complete member editor + declutter plan
2026-06-18 17:40:52 -04:00
Lucas Berger
9b62887f0f
feat(20-03): unify member editor + declutter admin members panel
...
- playwright-cli verified: Members tab shows tappable rows, no retired buttons
- Row tap opens 'Edit member' sheet; per-section saves keep sheet open
- 'Add member' trigger opens 'Add member' sheet in create mode
- Profile save fires 'Profile saved.' toast; sheet stays open (D-05)
- eslint + prettier + typecheck + vitest (275 tests) all pass
- Fix pre-existing prettier drift in docs/*, CLAUDE.md, README.md, api/admin.ts
2026-06-18 17:39:00 -04:00
Lucas Berger
9e6b004541
feat(20-03): rework AdminPage MemberRow + Add-member trigger; remove old surfaces
...
- MemberRow: whole-row role=button, aria-label='Edit {name}', trailing ChevronRight
- Admin badge on member.isAdmin (12px/600, --color-member-0 on --color-surface-dim)
- 'Add member' ghost trigger with Plus icon opens MemberEditorSheet in create mode
- Single MemberEditorSheet replaces CredentialSheet + ResetPasswordSheet mounts
- Removed: inline Local Accounts add-form, ResetPasswordSheet definition, create-form state
- Empty state: 'No members yet' / 'Add a member to get started.' (UI-SPEC copy)
2026-06-18 17:35:37 -04:00
Lucas Berger
b125a69b58
feat(20-03): add MemberEditorSheet with edit/create modes and per-section saves
...
- Edit mode: Profile (display name + admin toggle), Set new password, App password sections
- Create mode: single form with display name, username, initial/confirm password
- Per-section saves keep sheet open; create success closes sheet (D-05, D-07)
- Admin toggle role=switch, aria-checked; last-admin 409 shows inline error + reverts (D-03)
- Section 2 gated on member.hasLocalCredential; passwords never prefilled (T-20-07)
- App password save routes through saveCredential -> CalDAV validation (T-20-08)
- No Rotate/Add credential/Reset password copy (D-06)
2026-06-18 17:31:46 -04:00
Lucas Berger
10149a5966
docs(phase-20): update tracking after wave 1
2026-06-18 17:23:49 -04:00
Lucas Berger
258a188bde
chore: merge executor worktree (worktree-agent-af493496867aaca6d)
2026-06-18 17:21:59 -04:00
Lucas Berger
b377e9cb0a
chore: merge executor worktree (worktree-agent-afcc2c886302ea642)
2026-06-18 17:21:59 -04:00
Lucas Berger
4a179a943d
docs(20-01): complete member-profile update plan — SUMMARY + all CI gates green
2026-06-18 17:21:30 -04:00
Lucas Berger and Claude Sonnet 4.6
618991cf13
docs(20-02): complete plan 20-02 summary
...
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-18 17:21:26 -04:00
Lucas Berger and Claude Sonnet 4.6
5bcd8180c1
feat(20-02): add updateMemberProfile fetcher + AdminMember.isAdmin
...
- Add isAdmin: boolean to AdminMember interface (after color, before
hasCredential) — feeds the Phase 20 editor toggle initial state (D-02)
- Add updateMemberProfile(memberId, body) fetcher: PATCH /api/admin/members/:id,
credentials:include, redirect:manual, JSON body
- Maps 401/opaqueredirect → SessionExpiredError (existing convention)
- Maps 409/422 → Error('last-admin') sentinel (D-03 last-admin guard)
- Maps other non-ok → generic error
- All 50 tests pass; eslint + prettier + tsc --noEmit exit 0
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-18 17:20:13 -04:00
Lucas Berger
bc48632756
feat(20-01): add PATCH /members/:id member-profile update with last-admin guard
...
- Add isAdmin field to GET /members select and mapped member object (D-02)
- Add updateMemberSchema (displayName optional string, isAdmin optional boolean)
- Register adminRouter.patch('/members/:id') with noEchoHook and requireAdmin (inherited)
- Handler: parsePositiveIntParam id validation (400), existence check (404),
D-03 last-admin guard via COUNT(*) query (409), partial set() update (200)
- Fix Test D: switch to adminId2 for GET after self-demotion (adminId1 no longer admin)
- All 44 tests green including 7 new PATCH/isAdmin tests
2026-06-18 17:19:43 -04:00
Lucas Berger and Claude Sonnet 4.6
18da7e9476
test(20-02): add failing tests for updateMemberProfile + AdminMember.isAdmin
...
- 8 RED tests covering: PATCH URL contract, credentials/redirect shape,
void on 200, SessionExpiredError on 401/opaqueredirect, last-admin
sentinel on 409 and 422, generic error on 500
- 1 compile-time shape test for AdminMember.isAdmin: boolean
- All new tests fail (updateMemberProfile is not a function); 42 existing pass
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-18 17:18:21 -04:00
Lucas Berger
a0a82ac9b6
test(20-01): add failing tests for member-profile update + last-admin guard + isAdmin read
...
- Test A: PATCH displayName happy path → 200, GET reflects change
- Test B: PATCH isAdmin promote → 200, GET shows isAdmin true
- Test C: last-admin guard → 409 when only admin demotes self
- Test D: self-demotion → 200 when second admin exists
- Test E: non-admin PATCH → 403 (requireAdmin boundary)
- Test F: wrong-type body → 400 { error: "Invalid request" }; malformed :id → 400
- Test G: non-existent member id → 404
- Test H: GET /members includes boolean isAdmin per member
All 7 new tests fail RED for the right reasons (route 404 / isAdmin missing)
2026-06-18 17:18:14 -04:00
Lucas Berger
9b8b84edbe
docs(20): finalize phase plan (state, roadmap waves, patterns)
2026-06-18 17:06:40 -04:00
Lucas Berger
666845a192
docs(20): create phase plan
2026-06-18 17:04:21 -04:00
Lucas Berger
a3d89d0da0
docs(20): UI design contract
2026-06-18 16:51:46 -04:00
Lucas Berger
96193831c4
docs(20): UI design contract
2026-06-18 16:50:31 -04:00
Lucas Berger
fe0325ec43
docs(state): record phase 20 context session
2026-06-18 16:42:23 -04:00
Lucas Berger
91948919a8
docs(20): capture phase context
2026-06-18 16:42:19 -04:00
Lucas Berger
51ec9c3e82
docs(roadmap): add Phase 20 — Admin Member Editor & Form Declutter
2026-06-18 15:14:25 -04:00
Lucas Berger
b8d4a69b73
docs(phase-17): add security threat verification (9 closed, 0 open)
CI / changes (pull_request) Successful in 4s
CI / fast-checks (pull_request) Failing after 1m41s
CI / api (pull_request) Successful in 2m2s
CI / security (pull_request) Successful in 54s
CI / gate (pull_request) Has been cancelled
CI / harness (pull_request) Has been cancelled
2026-06-18 14:33:10 -04:00
Lucas Berger
881f2d2d18
test(17): complete UAT - 9 passed, 0 issues (playwright-cli verified)
2026-06-18 14:31:32 -04:00
Lucas Berger
6fa6725fe8
docs(17): add code review fix report (auto-loop, 3 iterations)
2026-06-18 14:06:03 -04:00
Lucas Berger
287ecae2f7
fix(17): CR-01 make focus-trap visibility filter tolerant of jsdom; IN-01 drop inert containment guard
2026-06-18 14:04:33 -04:00
Lucas Berger
89dee4f586
fix(17): IN-03 render visible Redirecting status during OIDC redirect
2026-06-18 13:57:31 -04:00
Lucas Berger
f7575ea2c3
fix(17): IN-02 document hand-maintained favicon.ico coupling
2026-06-18 13:56:48 -04:00
Lucas Berger
7578d48d3d
fix(17): IN-01 pull focus back into dialog when activeElement escapes
2026-06-18 13:56:32 -04:00
Lucas Berger
5b4625b41d
fix(17): WR-01 exclude hidden/zero-size nodes from focus-trap boundaries
2026-06-18 13:56:23 -04:00
Lucas Berger
4bc1e2a820
fix(17): IN-05 normalize AdminPage JSX formatting with Prettier
2026-06-18 13:48:34 -04:00
Lucas Berger
11b6b36cb9
fix(17): IN-07 memoize Intl.DateTimeFormat timezone resolution
2026-06-18 13:47:37 -04:00
Lucas Berger
2317833b74
fix(17): IN-04 remove dead brand placeholder tokens
2026-06-18 13:46:47 -04:00
Lucas Berger
3f4b7eac73
fix(17): IN-02 useCallback handleClose, drop exhaustive-deps disables
2026-06-18 13:46:27 -04:00
Lucas Berger
dd0b76128d
fix(17): WR-08 replace cp icon chain with cross-platform Node copy script
2026-06-18 13:45:36 -04:00
Lucas Berger
1c0f35748d
fix(17): WR-06 WR-07 clamp tz combobox active index; Tab-to-commit, blur-timer unmount cleanup
2026-06-18 13:44:44 -04:00
Lucas Berger
f601c0c408
fix(17): WR-02 WR-03 WR-04 IN-06 admin tab Home/End+wrap; toast re-announce, wrap, z-index 400
2026-06-18 13:43:10 -04:00
Lucas Berger
fb30800e9a
fix(17): WR-01 trap focus in modal dialogs via useFocusTrap
2026-06-18 13:41:33 -04:00
Lucas Berger
a4a7438641
fix(17): WR-05 IN-03 IN-01 resize-aware useIsPhone hook; OidcRedirect side-effect in effect
2026-06-18 13:40:00 -04:00
Lucas Berger
c2ceebf130
docs(17): add deep code review report
2026-06-18 13:35:10 -04:00
Lucas Berger and Claude Opus 4.8
a986c74963
docs(phase-17): mark phase complete (pending human verification)
...
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com >
2026-06-18 13:11:35 -04:00
Lucas Berger and Claude Opus 4.8
fcc02e3833
docs(17): add phase verification report (10/10 decisions delivered; human_needed for device-only checks)
...
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com >
2026-06-18 13:11:23 -04:00
Lucas Berger and Claude Opus 4.8
9730d3dcdb
docs(17): add code review report
...
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com >
2026-06-18 13:06:20 -04:00
Lucas Berger and Claude Opus 4.8
ea49a4dc83
docs(phase-17): update tracking after wave 2
...
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com >
2026-06-18 13:03:12 -04:00
Lucas Berger and Claude Opus 4.8
b5fcd1d172
fix(17): resolve post-merge wave 2 integration issues
...
- SettingsSheet: void the navigate('/login') promise (react-router v7 returns Promise) — eslint no-floating-promises
- InstructionSheet.test: wrap SettingsSheet render in MemoryRouter — 17-05 added useNavigate() which needs Router context
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com >
2026-06-18 13:01:39 -04:00
Lucas Berger
4887ba1b5f
chore: merge executor worktree (worktree-agent-a12887546a61a8053)
2026-06-18 12:58:59 -04:00
Lucas Berger
aaf754d938
chore: merge executor worktree (worktree-agent-a65077bbd9885bf7e)
2026-06-18 12:58:58 -04:00
Lucas Berger
9e39a5c492
chore: merge executor worktree (worktree-agent-ad448992e936c77aa)
2026-06-18 12:58:57 -04:00
Lucas Berger
29f3d62312
chore: merge executor worktree (worktree-agent-a1f3ad1ab5d67e70c)
2026-06-18 12:58:56 -04:00
Lucas Berger
f4c65d478a
docs(17-06): complete admin polish plan — toasts + two-tab ARIA nav + e2e assertions
2026-06-18 12:58:06 -04:00
Lucas Berger
944045cd7e
test(17-06): add admin two-tab ARIA and keyboard assertions to admin.spec.ts
...
- Add 'Admin two-tab ARIA strip (D-10)' describe block: tablist visible,
both named tabs visible, ArrowRight/ArrowLeft keyboard switching,
panel aria-labelledby, phone overflow check
- Add 'Admin success toast structure (D-08)' describe: role=status absent on load
- Satisfies Wave 0 admin-ARIA CI requirement — 12/12 tests pass on pixel profile
2026-06-18 12:56:34 -04:00
Lucas Berger
caff8b4b0a
docs(17-05): complete logout control + sheet centering plan
...
- Sign out control (D-07): LogOut icon, handleSignOut fire-and-best-effort, navigate /login
- Desktop centering (D-09): phone/desktop style branch on SettingsSheet, ChangePasswordSheet, LinkOidcSheet, CredentialSheet
- playwright-cli verified: centered modal @1280x720, bottom-sheet @390x844, Sign out redirects to /login
2026-06-18 12:54:43 -04:00
Lucas Berger
28e9ca9840
docs(17-03): complete phone layout overlap fix plan — SUMMARY.md
...
FAB lifted above BottomTabBar, phone content padding added, D-01
regression guard committed to layout.spec.ts; 3-profile e2e sweep green.
2026-06-18 12:54:30 -04:00
Lucas Berger
620d64138a
feat(17-06): add success toasts to admin create-member and reset-password
...
- Add toast state + 3000ms auto-dismiss useEffect to AdminPage
- Set toast 'Member added.' in createMemberMutation.onSuccess
- Propagate 'Password reset.' up from ResetPasswordSheet via onSuccess callback
- Render role=status/aria-live=polite toast with CheckCircle icon
- Phone toast offset uses calc(var(--bottom-chrome-h) + var(--space-4)) to clear BottomTabBar
2026-06-18 12:53:12 -04:00
Lucas Berger
b71238634f
feat(17-05): add phone/desktop style branch to CredentialSheet (D-09)
...
- Add window.matchMedia('(max-width: 767px)') phone check
- Desktop branch: position fixed, top/left 50%, translate(-50%, -50%), maxWidth 480px, borderRadius 12px
- Phone branch: unchanged bottom-sheet (bottom 0, left 0, right 0, borderRadius 12px 12px 0 0)
- role=dialog, aria-modal, aria-label unchanged — only position CSS branched
- SettingsSheet, ChangePasswordSheet, LinkOidcSheet centering in prior commit (Task 1)
2026-06-18 12:52:59 -04:00
Lucas Berger
132a5e4eae
feat(17-05): add Sign out control with handleSignOut to SettingsSheet (D-07)
...
- Add LogOut icon (lucide-react) and fetchLocalLogout (api/client) imports
- Add useNavigate (react-router) for post-logout redirect
- Implement handleSignOut: fire-and-best-effort try/catch, navigate to /login in both branches
- Add Sign out button row at bottom of sheet (44px tap target, var(--color-destructive), divider separator)
- Always navigates to /login even on API failure (server cookie cleared or expired)
2026-06-18 12:52:48 -04:00
Lucas Berger
4cb16f8271
docs(17-04): complete brand wiring plan — BrandSlot logo, favicons, maskable icon fix, accent
...
- BrandSlot: placeholder div replaced with decorative logo img (ce95aa3 )
- tokens.css: --brand-logo-border-radius 0, --color-member-0 #e8915a (df578fd )
- index.html: favicon.svg + favicon.ico links, theme-color #e8915a (df578fd )
- vite.config.ts: maskable icon fixed to /icon-maskable-512.png, theme_color #e8915a (df578fd )
- Build: green; manifest.webmanifest verified correct
2026-06-18 12:51:58 -04:00
Lucas Berger
85a803fba6
test(17-03): add FAB↔BottomTabBar overlap regression guard to layout.spec.ts
...
- New test: "New Event FAB does not overlap BottomTabBar (A — phone only)"
- Skips on desktop profile; runs iphone + pixel (the profiles that exposed D-01)
- Asserts fabBox.y + fabBox.height <= navBox.y (FAB bottom ≤ bar top)
- Confirms Task 1 fix resolves the seed defect — passes green on both profiles
2026-06-18 12:51:32 -04:00
Lucas Berger
df578fd7b7
feat(17-04): wire favicons + theme-color in index.html, fix maskable icon + accent in manifest
...
- index.html: add favicon.svg (SVG, modern browsers first) + favicon.ico (legacy) links
- index.html: update theme-color from #4A90D9 to approved #e8915a (warm amber)
- vite.config.ts: fix maskable icon — reference /icon-maskable-512.png (separate file) not /icon-512.png
- vite.config.ts: update manifest theme_color to #e8915a to match index.html
- tokens.css: update --color-member-0 to #e8915a (warm amber, Variant B, operator-approved 17-02)
- --sx-color-primary follows automatically via var(--color-member-0)
2026-06-18 12:50:50 -04:00
Lucas Berger
ce95aa3e6b
feat(17-04): wire logo img into BrandSlot, set --brand-logo-border-radius 0
...
- Replace placeholder FS div with decorative <img src="/logo.svg" alt="" aria-hidden>
- Apply Surface B-1 style (width/height brand-logo-size, borderRadius token, contain/block)
- Update --brand-logo-border-radius from 50% to 0 (SVG draws its own rx=104 shape)
- h1 FamilySync and tagline p unchanged; LoginPage.tsx untouched (seam contract honored)
- No dangerouslySetInnerHTML (T-05-24 invariant maintained)
2026-06-18 12:48:55 -04:00
Lucas Berger
5e1c714894
fix(17-03): lift FAB above BottomTabBar and reserve phone content padding
...
- CalendarShell.tsx: FAB bottom changed from var(--space-6) to
calc(var(--bottom-chrome-h) + var(--space-6)) — sits 24px above bar
- App.tsx: contentStyle gains phone-only paddingBottom: var(--bottom-chrome-h)
via spread pattern ...(phone ? {...} : {}) — desktop unchanged
2026-06-18 12:48:35 -04:00
Lucas Berger
9e080fb22a
docs(phase-17): update tracking after wave 1
2026-06-18 12:45:49 -04:00
Lucas Berger
65e6222944
chore: merge executor worktree (worktree-agent-af89750bf86857964)
2026-06-18 12:44:24 -04:00
Lucas Berger
58d11caee0
chore: merge executor worktree (worktree-agent-a1fb88aa75fd00c8f)
2026-06-18 12:44:23 -04:00
Lucas Berger
d917157c63
docs(17-02): complete branding assets plan summary
...
Records approved brand decisions for plan 17-04:
- logo art approved (family-house redesign)
- brand accent #e8915a (warm amber)
- --brand-logo-border-radius: 0
2026-06-18 12:43:45 -04:00
Lucas Berger
4c99470c1a
feat(17-02): apply approved family-house logo + regenerate icon set
...
- Overwrite logo.svg with approved higher-contrast family-house SVG
(warm peach gradient bg, amber roof, bold white walls, heart finial,
three clearly-spaced family figures in rose/gold/blue)
- Regenerate full icon/favicon set from new art:
favicon.svg, favicon.ico (967 B), icon-192.png (192x192),
icon-512.png (512x512), icon-maskable-512.png (512x512 safe-zone),
apple-touch-icon.png (180x180)
- Approved brand decisions recorded for plan 17-04:
accent #e8915a, --brand-logo-border-radius: 0
2026-06-18 12:42:43 -04:00
Lucas Berger
d01ec2388c
docs(17-01): complete token groundwork plan — SUMMARY
...
tokens.css restructured to :root,[data-theme=light] combined selector;
--bottom-chrome-h added; all --sx-color-* overrides intact; build green;
layout.spec.ts pixel profile 15/15 pass; Schedule-X colors verified.
2026-06-18 12:14:45 -04:00
Lucas Berger
b364573285
feat(17-02): generate full icon/favicon set from logo.svg (Task 2)
...
- Run @vite-pwa/assets-generator minimal2023Preset against public/logo.svg
- Produce: favicon.ico (861 B, non-trivial), favicon.svg, icon-192.png (1617 B),
icon-512.png (4221 B), icon-maskable-512.png (3353 B, 512x512 distinct maskable
with safe-zone padding), apple-touch-icon.png (1110 B, 180x180)
- Replace 3 placeholder stubs with real generated assets
- Update pwa:icons script to include post-generation canonical rename step
- Add generator intermediate output filenames to .gitignore
2026-06-18 12:13:50 -04:00
Lucas Berger
c2f89bd55f
feat(17-01): restructure tokens.css to combined :root,[data-theme=light] selector + add --bottom-chrome-h
...
- Change :root { to :root, [data-theme="light"] { (D-06 combined selector)
- Add --bottom-chrome-h: calc(56px + env(safe-area-inset-bottom, 0px)) to spacing scale
- Keep all 12 --sx-color-* overrides inside the combined block (cascade unchanged)
- Keep --brand-logo-* tokens inside the combined block (verbatim, no value changes)
- Add dark-theme stub as comment-only (Phase 999.20 fills values; no live rule)
- All existing values unchanged; PWA build passes; Schedule-X colors verified via playwright-cli
2026-06-18 12:12:42 -04:00
Lucas Berger
7db9005645
feat(17-02): install @vite-pwa/assets-generator, author logo.svg, add pwa-assets.config.ts
...
- Add @vite-pwa/assets-generator@1.0.2 as devDependency in apps/pwa
- Add pwa:icons script (pwa-assets-generator generate) to apps/pwa/package.json
- Approve sharp build scripts in pnpm-workspace.yaml (required for @vite-pwa/assets-generator)
- Hand-author apps/pwa/public/logo.svg: warm/rounded/at-home family scene with house, two adults, child, heart — square 512x512 viewBox, self-contained, text-free
- Create apps/pwa/pwa-assets.config.ts with minimal2023Preset, images: ['public/logo.svg'], no overrideManifestIcons
2026-06-18 12:12:17 -04:00
Lucas Berger
eb0db8beef
docs(17): create phase plan
2026-06-18 11:36:21 -04:00
Lucas Berger
280438b2d3
docs(17): create phase plan (6 plans, 2 waves) — UI optimization & polish
2026-06-18 11:34:04 -04:00
Lucas Berger
28cf79754a
docs(17): add validation strategy
2026-06-18 11:19:24 -04:00
Lucas Berger
f789a67f95
docs(17): research phase domain
2026-06-18 11:17:44 -04:00
Lucas Berger
a1457a5b30
docs(17): UI design contract
2026-06-18 10:59:25 -04:00
Lucas Berger
efeee02a36
Merge remote-tracking branch 'origin/main' into gsd/phase-17-ui-optimization-polish
...
# Conflicts:
# .planning/STATE.md
2026-06-18 10:08:45 -04:00
Lucas Berger and Claude Opus 4.8
cfe84715d5
docs: add developer profile section to CLAUDE.md
...
Publish / publish (push) Successful in 11s
Generated by /gsd-profile-user from session analysis (8 dimensions).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com >
2026-06-18 10:07:03 -04:00
Lucas Berger
1e2cc52659
docs: refresh project documentation against current codebase
Publish / publish (push) Successful in 26s
2026-06-18 06:44:29 -04:00
Lucas Berger and Claude Opus 4.8
b6490feff4
fix(19): satisfy CI fast-checks + secret scan
...
CI / changes (pull_request) Successful in 9s
CI / api (pull_request) Successful in 3m2s
CI / fast-checks (pull_request) Successful in 4m20s
CI / security (pull_request) Successful in 1m14s
CI / harness (pull_request) Successful in 6m56s
CI / gate (pull_request) Successful in 2s
Lint (eslint --max-warnings 0):
- index.ts: disable no-unsafe-argument on the type-only Context mismatch when
delegating to the OIDC handler inside the local-session skip wrapper
- localAuth.ts: handleLogout is sync (no await) — drop async (require-await)
- devBypass.ts: disable detect-possible-timing-attacks on the public well-known
dev-placeholder string compare (not a secret comparison)
- remove dead code / unused bindings flagged by no-unused-vars: makeTestApp
(localSession.test), makeUnauthContext + BrowserContext import (login.spec),
unused memberId (admin.test), unused txSelectCount counter (me.test)
- localAuthMiddleware.test / me.test: fix unused + reflow-detached
eslint-disable directives
Format: prettier --write across the 20 Phase-19 files that were never formatted.
Secret scan (gitleaks): allowlist two false positives — the synthetic >=32-char
TEST_SECRET in localSession.test.ts, and .planning/ design prose (a generic-api-key
regex hit on "credential atomically, 409-equivalent"). Neither is a real secret.
Verified locally: format:check, lint, typecheck, md:lint, gitleaks (no leaks),
PWA 266/266, API 452/452.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com >
2026-06-17 23:05:15 -04:00
Lucas Berger
91ab9d1f78
docs(19): ship phase 19 — PR #23
2026-06-17 22:49:45 -04:00
Lucas Berger
abf7be782a
docs(phase-19): add security threat verification (28/28 closed, threats_open: 0)
CI / changes (pull_request) Successful in 10s
CI / fast-checks (pull_request) Failing after 2m17s
CI / api (pull_request) Successful in 2m51s
CI / security (pull_request) Failing after 12s
CI / harness (pull_request) Successful in 5m9s
CI / gate (pull_request) Failing after 2s
2026-06-17 22:47:45 -04:00
Lucas Berger
f3af130e9e
docs(17): add workstream D — 4 UI findings from Phase 19 UAT (logout button, admin feedback, popup centering, admin nav)
2026-06-17 22:34:18 -04:00
Lucas Berger
af0a70ccec
test(19): complete UAT — Tests 1-3 pass live, 4 resolved-by-fix, 5→ship; 4 UI findings routed to Phase 17
2026-06-17 22:32:52 -04:00
Lucas Berger
73dd6a2383
docs(19): re-review after fixes — status clean (0 critical/warning, 2 info)
2026-06-17 20:50:25 -04:00
Lucas Berger
9cccf17ef9
chore: enable MemPalace discuss-time recall + KG mirror
2026-06-17 20:45:39 -04:00
Lucas Berger
5f74ae965d
docs(19): add code review fix report
2026-06-17 20:42:51 -04:00
Lucas Berger
cef2c66de5
merge(19): land code-review fixes (CR-01..04, BL-01..04, WR-01..07, IN-01..04)
2026-06-17 20:39:49 -04:00
Lucas Berger
2691dd0f95
fix(19): IN-04 enforce single-use OIDC-link nonce to prevent state replay
2026-06-17 20:37:09 -04:00
Lucas Berger
83e23d760d
docs(state): record phase 17 context session
2026-06-17 20:37:02 -04:00
Lucas Berger
3784762817
docs(17): capture phase context (layout polish + branding + theme groundwork; dark mode/styling deferred)
2026-06-17 20:37:02 -04:00
Lucas Berger
f02521dd02
fix(19): IN-03 evict stale loginAttempts entries to bound in-memory map growth
2026-06-17 20:35:43 -04:00
Lucas Berger
e392bf2eb7
fix(19): IN-02 add lockstep test pinning inlined scrypt params against canonical verifyPassword
2026-06-17 20:34:58 -04:00
Lucas Berger
f2fc1404d4
fix(19): IN-01 validate LOCAL_SESSION_EXPIRES coercion (fallback on NaN/non-positive)
2026-06-17 20:34:14 -04:00
Lucas Berger
916fb34f17
docs: add backlog items 999.20 (dark mode/theming) + 999.21 (styling refresh)
2026-06-17 20:34:02 -04:00
Lucas Berger
4bd6b2c057
fix(19): WR-05 add no-echo tests for admin create-member and me password hook sites
2026-06-17 20:33:46 -04:00
Lucas Berger
32bdd1e92d
fix(19): WR-07 reject route ids with trailing garbage via strict integer parse
2026-06-17 20:32:26 -04:00
Lucas Berger
4cf2ad4bff
fix(19): WR-06 stop sliding the rate-limit cooldown window on rejected attempts
2026-06-17 20:31:07 -04:00
Lucas Berger
30ad25c026
fix(19): WR-03 make scrypt hashing async (threadpool) to avoid event-loop starvation DoS
2026-06-17 20:30:28 -04:00