You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Purpose: this issue is the durable roadmap for TortoiseWolfe/ScriptHammer. The body below is always-current — active arc, next 3 sessions queued, backlog. Comments are the audit trail. The prime prompt at the top tells a fresh Claude session to read this body first.
✅ Updated 2026-06-08.Two of the three unblock-me items turned out to be autonomous and are DONE. (1) All 11 payment edge functions deployed to prod via the Supabase Management API (POST /functions/deploy, multipart raw-source) — no CLI needed; the SUPABASE_ACCESS_TOKEN + ref in .env authenticate, and zero functions were deployed before. So the #5 webhook code (grace-period, the supabase.sql increment fix, the PayPal failed-payment branch) is now LIVE. See [[lesson_edge_function_deploy_management_api]]. (2) #5 grace-period UI + dup-guard functionally verified (DB-only, no creds): seeded a grace_period row → loaded /account/subscriptions as the test user via Playwright MCP → "Grace period: 5 days remaining" + badge rendered through real RLS; a 2nd live insert hit idx_subscriptions_one_live_per_user (23505); all artifacts cleaned up. (3) #45 Sentry error monitoring SHIPPED (PR #145, squash-merged 8a53e9f, closed #45) — client-only @sentry/react (static-export-safe), consent-gated via ConsentContext, PII-scrubbed beforeSend, single capture chokepoint in error-handler, CSP updated. Inert until a DSN is set (no-op while NEXT_PUBLIC_SENTRY_DSN is empty). ONLY remaining blocker: Stripe + PayPal sandbox creds (for live payment traffic + un-skipping the cred-blocked E2E) and a Sentry DSN (to flip #45 on). Both are user-supplied; all engineering is done. (4) Bonus autonomous slice SHIPPED (PR #146, squash-merged 78a5051): a subscription E2E seed fixture (seedIsolatedSubscription) un-skipped the grace-period-countdown + duplicate-prevention (23505) tests — verified green in CI (skip count 85→27 via this + the audit reclassification; the old "85 cred-blocked" figure was wrong — only ~6 are actually cred-gated, per the regenerated docs/payment-e2e-skip-index.md). (5) Unified payment hub + realtime SHIPPED (PR #147, squash-merged 89ff7f5): consolidated /payment/dashboard + /account/subscriptions into one tabbed /payment hub (Overview/Subscriptions, ?tab= deep-link) and made PaymentHistory + SubscriptionManager live via Supabase Realtime (reusable usePaymentResultsRealtime/useSubscriptionsRealtime hooks). Root-cause caught by live E2E: payment_results/subscriptions were NOT in the supabase_realtime publication → the channel got no events; added them (migration + applied to prod), verified counter 2→3 live. Un-skipped 4 more 06-realtime tests (skip count 27→23). See [[lesson_realtime_publication_membership]].
Prime prompt (copy from here into a fresh Claude session)
/prep
Then check this issue (TortoiseWolfe/ScriptHammer#115) — its BODY is the current roadmap. Read everything below the prime prompt: active arc, next 3 sessions queued, backlog. The most recent COMMENT on this issue is the audit trail of what changed since the previous session.
Supplementary context (read if the body's roadmap references them or if the user's first message takes us off-roadmap):
1. `~/.claude/projects/-home-TurtleWolfe-repos-ScriptHammer/memory/MEMORY.md` — top of the index lists NON-NEGOTIABLE user preferences + recently-banked lessons. Read these first; they're binding.
2. `git log --oneline -20` — what shipped recently.
3. Open issues (`gh issue list --repo TortoiseWolfe/ScriptHammer --state open`) — most are tagged `template-v1-out-of-scope` (Eval-Backlog / Gap-Audit). Treat those as deferred backlog, not active work.
4. Open PRs (`gh pr list --repo TortoiseWolfe/ScriptHammer --state open`).
Operational reminders from MEMORY.md / CLAUDE.md you'll trip over otherwise:
- ALWAYS prefer cleaner long-term solutions over quick hacks. Never offer a hack as the primary recommendation. Fix root cause, not symptoms.
- SECURITY DEFINER to bypass RLS is a hack, not a fix.
- CI honesty: a green job `conclusion` ≠ 0 flaky — `retries:2` masks retry-recovered failures. ALWAYS read per-job `flaky`/`failed` lines + `gh api .../commits/<sha>/check-runs` annotations before claiming clean or merging.
- Pushing to `.github/workflows/**` needs SSH (gh HTTPS token lacks `workflow` scope). If the session's ssh-agent is empty, your key may be in another `/tmp/ssh-*/agent.*` socket — probe them and `export SSH_AUTH_SOCK=<the one that authenticates>`.
- Supabase prod can DRIFT from the monolithic migration. Verify schema/triggers against the LIVE DB (`pg_get_triggerdef`, `information_schema.columns`), never trust issue text or the migration file alone. See [[lesson_prod_schema_drift_audit_logs]] + [[lesson_subscriptionmanager_schema_drift]]. Mgmt API DDL: build the JSON payload from a FILE, not bash `$$` interpolation.
- Edge-function CODE merging ≠ deployed. ScriptHammer has NO CI that deploys Supabase edge functions — they need a manual `supabase functions deploy <name>`. Don't claim a webhook change is live in prod on merge.
- Honest contrast tests: jsdom can't measure DaisyUI contrast (tokens resolve empty → silent gray-on-gray pass). Must be Playwright + read colors through a `<canvas>` (Chromium serializes OKLCH custom props as `oklch()` strings, not rgb()). See [[lesson_oklch_contrast_canvas_playwright]].
- Regenerate Supabase types via the Management API (GET /v1/projects/{ref}/types/typescript), NOT a local CLI install.
- CI mutex serializes E2E runs; PR E2E is chromium-only (firefox/webkit on push-to-main + cron, or the `full-e2e` PR label). docs/`.claude`/`.specify`/`features`/md changes skip E2E (paths-ignore). `--admin` merge is OK when all gates+smoke are green and only unrelated chromium-gen shards (or a documented unrelated retry-recovered flake) remain.
Then either start on the roadmap's "next session should" item, or ask the user if they want to deviate.
Stop reading here when priming — everything below is the roadmap
Roadmap
Active arc
FINAL UNBLOCK — only credentials remain. All autonomous engineering is shipped. The two "blocked" items that turned out to be autonomous (the #5 edge-function deploy + verify, and the #45 Sentry scaffold) are DONE. What's left needs values only the user can create.
Status: 2 of 3 unblock-items DONE (2026-06-08). The remaining work is gated purely on user-supplied creds.
Only one cred-gated session remains; everything else is design-call backlog.
Session +1 (unblocked by Stripe/PayPal sandbox creds): Payments backend live-acceptance (#100/#103/#104/#105/#106) — the function code is already deployed to prod. Set the provider secrets via POST /v1/projects/{ref}/secrets (Stripe secret + STRIPE_WEBHOOK_SECRET; PayPal client-secret + PAYPAL_WEBHOOK_ID), run the live-acceptance E2E, un-skip the ~6 cred-blocked tests per docs/payment-e2e-skip-index.md, then close #105/#106.
First action: confirm sandbox creds are available; set them via the Management API secrets endpoint (build the JSON from a file), then un-skip.
Quick follow-up (unblocked by a Sentry DSN): flip #45 live — set NEXT_PUBLIC_SENTRY_DSN in .env + the Actions secret. No code change; verify init fires after analytics consent and an error reaches Sentry post-scrub.
If the user has NO creds ready, the only remaining candidates are design-call / speculative items — flag that they need a product/design decision first; don't start them blind:
Speculative realtime widgets (deferred this session, deliberately): reconnection-button UI, batch-update grouping, real-time error toast, payment chart (the remaining 06-realtime skips). No clear user need; a chart adds a dependency. Out of scope for a template unless the user asks.
E2E stability — known flaky: oauth-csrf.spec.ts:78 webkit (live github.com nav) and messaging-scroll.spec.ts:292 ("Jump button appears when scrolled" — fixture-height/timing flake, chromium + webkit, retry-recovers; documented in CLAUDE.md). Both retry-recover; harden if noisy.
Reusable substrate (on main):embed-theme.ts + useEmbedThemeColor (theme→embed color, contrast-gated); EmailProviderHealth organism; the unified /payment hub (tabbed shell at src/app/payment/, ?tab= deep-link via SearchParamsReader, synchronous URL→tab init) — the canonical multi-surface-page pattern; the idx_subscriptions_one_live_per_user dup-guard pattern; PaymentQueuePanel (offline-queue mgmt UI); useConnections realtime-badge pattern; startFormQueueFallback (foreground queue flush for non-SyncManager browsers); resolveParticipantName (deleted-vs-unknown profile); viewport-fit=cover + env(safe-area-inset-*) for iOS input safe-area. Plus [Gap-Audit] 044 Error Handler Integrations: Sentry/LogRocket integration + PII scrubbing + session replay #45: src/lib/monitoring/ (scrub.ts PII scrubber, sentry.ts consent-gated client init, SentryMonitor) — the consent-gated-3rd-party-SDK pattern. Plus feat(payment): unified /payment hub with realtime PaymentHistory + Subscriptions #147: usePaymentResultsRealtime/useSubscriptionsRealtime (debounced postgres_changes + connection-status, optional realtime prop) — the reusable realtime-list pattern (REMEMBER: the table must be in the supabase_realtime publication, see [[lesson_realtime_publication_membership]]). CLI-free edge-function deploy via the Management API (see [[lesson_edge_function_deploy_management_api]]).
Next session should
Ask the user for the two remaining credentials and execute the instant either lands: (1) Stripe + PayPal sandbox creds → set via POST /v1/projects/{ref}/secrets, run payment live-acceptance, un-skip the ~6 truly cred-gated E2E (#3 / #100/#103/#104/#105/#106); (2) a Sentry DSN → drop into .env + Actions secret to flip #45 live. All engineering is shipped — the 11 edge functions are deployed; #5 grace/dup/realtime verified; #45 merged (needs the DSN); the /payment hub + realtime shipped (PR #147). Of the 23 remaining payment E2E skips, only ~6 are cred-gated; the rest are speculative widgets / offline-queue Dexie / perf — all design-call backlog. Override: if the user's first message has a different priority, follow the user.
Why this exists
Sessions end. The next session starts cold. Without a single canonical "what was the world like when we last stopped + here's what to do next" pointer, the new model wastes context wandering. This issue is the one URL to paste into a fresh chat. The BODY carries the plan; comments form the audit trail.
How to maintain
Run /session-prime at session-end. The skill rewrites the body to reflect what changed in the roadmap and appends a comment with the audit trail.
If the prime prompt itself becomes stale (memory file renamed, project changed shape), edit the body's prime-prompt block directly.
Purpose: this issue is the durable roadmap for TortoiseWolfe/ScriptHammer. The body below is always-current — active arc, next 3 sessions queued, backlog. Comments are the audit trail. The prime prompt at the top tells a fresh Claude session to read this body first.
Prime prompt (copy from here into a fresh Claude session)
Stop reading here when priming — everything below is the roadmap
Roadmap
Active arc
FINAL UNBLOCK — only credentials remain. All autonomous engineering is shipped. The two "blocked" items that turned out to be autonomous (the #5 edge-function deploy + verify, and the #45 Sentry scaffold) are DONE. What's left needs values only the user can create.
Status: 2 of 3 unblock-items DONE (2026-06-08). The remaining work is gated purely on user-supplied creds.
Remaining tasks (what only the user can provide):
(1) [Eval-Backlog] SUBSCRIPTION-MGMT: subscription management route + 4 edge functions + grace-period wiring #5 edge-function deploy + verify— DONE. All 11 functions deployed via the Management API (CLI-free); grace-period UI + 23505 dup-guard functionally verified. See [[lesson_edge_function_deploy_management_api]].(2) [Gap-Audit] 044 Error Handler Integrations: Sentry/LogRocket integration + PII scrubbing + session replay #45 error monitoring— DONE. Sentry chosen, scaffolded DSN-less (PR feat(monitoring): #45 consent-gated Sentry error monitoring (client-only, PII-scrubbed) #145, closed [Gap-Audit] 044 Error Handler Integrations: Sentry/LogRocket integration + PII scrubbing + session replay #45). Inert until a DSN is set.POST /v1/projects/{ref}/secrets(Stripe secret +STRIPE_WEBHOOK_SECRET; PayPal client-secret +PAYPAL_WEBHOOK_ID). Then run live-acceptance E2E, un-skip the 6 truly cred-blocked tests perdocs/payment-e2e-skip-index.md([Gap-Audit] tests/e2e/payment/: 84 test.skip — index by blocker #53 — count corrected from the stale "85"; only ~6 are cred-gated), close [Phase 0e] Subscription lifecycle: cancel-subscription + resume-subscription (~3h) #105/[Phase 0f] Shared infra + un-skip 86 E2E payment tests (~2h) #106.NEXT_PUBLIC_SENTRY_DSNin.env+ the GitHub Actions secret. Monitoring activates with zero code change (after analytics consent).Blockers (the ONLY things left, both user-supplied):
POST /secrets, then live-acceptance + un-skip ([Eval-Backlog] PAYMENT-DASHBOARD: user-facing payment dashboard route #3 payment backend).Next 3 sessions queued
Only one cred-gated session remains; everything else is design-call backlog.
Session +1 (unblocked by Stripe/PayPal sandbox creds): Payments backend live-acceptance (#100/#103/#104/#105/#106) — the function code is already deployed to prod. Set the provider secrets via
POST /v1/projects/{ref}/secrets(Stripe secret +STRIPE_WEBHOOK_SECRET; PayPal client-secret +PAYPAL_WEBHOOK_ID), run the live-acceptance E2E, un-skip the ~6 cred-blocked tests perdocs/payment-e2e-skip-index.md, then close #105/#106.Quick follow-up (unblocked by a Sentry DSN): flip #45 live — set
NEXT_PUBLIC_SENTRY_DSNin.env+ the Actions secret. No code change; verify init fires after analytics consent and an error reaches Sentry post-scrub.If the user has NO creds ready, the only remaining candidates are design-call / speculative items — flag that they need a product/design decision first; don't start them blind:
PaymentQueueV2/queuedOperations→ needs an in-page IndexedDB seed fixture (NOT a DB insert) + the empty test bodies written. Autonomous but non-trivial.Backlog (no scheduled position)
seedIsolatedSubscription+seedIsolatedPaymentfixtures, 6 payment tests un-skipped total, green in CI). Remaining: the cancel flow (drives thecancel-subscriptionEdge Function — needs the deployed fn exercised with provider config) and the offline-queue E2E (empty stubs + client-side Dexie — see speculative/deferred list above).information_schema. See [[lesson_prod_schema_drift_audit_logs]] + [[lesson_subscriptionmanager_schema_drift]].oauth-csrf.spec.ts:78webkit (live github.com nav) andmessaging-scroll.spec.ts:292("Jump button appears when scrolled" — fixture-height/timing flake, chromium + webkit, retry-recovers; documented in CLAUDE.md). Both retry-recover; harden if noisy.embed-theme.ts+useEmbedThemeColor(theme→embed color, contrast-gated);EmailProviderHealthorganism; the unified/paymenthub (tabbed shell atsrc/app/payment/,?tab=deep-link viaSearchParamsReader, synchronous URL→tab init) — the canonical multi-surface-page pattern; theidx_subscriptions_one_live_per_userdup-guard pattern;PaymentQueuePanel(offline-queue mgmt UI);useConnectionsrealtime-badge pattern;startFormQueueFallback(foreground queue flush for non-SyncManager browsers);resolveParticipantName(deleted-vs-unknown profile); viewport-fit=cover +env(safe-area-inset-*)for iOS input safe-area. Plus [Gap-Audit] 044 Error Handler Integrations: Sentry/LogRocket integration + PII scrubbing + session replay #45:src/lib/monitoring/(scrub.tsPII scrubber,sentry.tsconsent-gated client init,SentryMonitor) — the consent-gated-3rd-party-SDK pattern. Plus feat(payment): unified /payment hub with realtime PaymentHistory + Subscriptions #147:usePaymentResultsRealtime/useSubscriptionsRealtime(debounced postgres_changes + connection-status, optionalrealtimeprop) — the reusable realtime-list pattern (REMEMBER: the table must be in thesupabase_realtimepublication, see [[lesson_realtime_publication_membership]]). CLI-free edge-function deploy via the Management API (see [[lesson_edge_function_deploy_management_api]]).Next session should
Ask the user for the two remaining credentials and execute the instant either lands: (1) Stripe + PayPal sandbox creds → set via
POST /v1/projects/{ref}/secrets, run payment live-acceptance, un-skip the ~6 truly cred-gated E2E (#3 / #100/#103/#104/#105/#106); (2) a Sentry DSN → drop into.env+ Actions secret to flip #45 live. All engineering is shipped — the 11 edge functions are deployed; #5 grace/dup/realtime verified; #45 merged (needs the DSN); the/paymenthub + realtime shipped (PR #147). Of the 23 remaining payment E2E skips, only ~6 are cred-gated; the rest are speculative widgets / offline-queue Dexie / perf — all design-call backlog. Override: if the user's first message has a different priority, follow the user.Why this exists
Sessions end. The next session starts cold. Without a single canonical "what was the world like when we last stopped + here's what to do next" pointer, the new model wastes context wandering. This issue is the one URL to paste into a fresh chat. The BODY carries the plan; comments form the audit trail.
How to maintain
Run
/session-primeat session-end. The skill rewrites the body to reflect what changed in the roadmap and appends a comment with the audit trail.If the prime prompt itself becomes stale (memory file renamed, project changed shape), edit the body's prime-prompt block directly.