Skip to content

ScriptHammer upstream sync — 461 commits of drift, triaged #77

Description

@TortoiseWolfe

SpokeToWork was squash-forked from ScriptHammer in Dec 2025. There is no shared git history and no upstream remote, so drift can only be measured by comparing files — git log will never show it.

As of 2026-08-01, upstream has landed 461 commits since this fork's last commit (3cca5af, 2026-04-20).

Most of that is divergence we should never import. This epic exists so nobody re-derives that judgement, and — more importantly — so nobody tries to "catch up to upstream" wholesale.


🚫 DO NOT IMPORT

Upstream has grown in directions that have no SpokeToWork surface. Importing any of this would be pure cost.

Upstream subsystem Why not
src/twin/, src/world/, src/stage/, src/packs/, src/post/ Cesium + three.js digital-twin renderer. No consumer here.
scripts/bake/*, sites/*.json, public/twins/, sites/_warehouse/ LiDAR/OSM/3DEP bake pipeline for the twin world.
src/lib/manifest.ts (20 upstream commits) Despite the name this is not the PWA manifest — it's the baked-twin runtime contract. Do not "sync" it against ours.
Stripe / PayPal subscription work, supabase/functions/{cancel,create,resume,retry}-subscription, checkout/capture functions We have payment-demo only, no live subscription surface.
Calendly / @calcom/embed-react Not a SpokeToWork surface.
src/services/messaging/providers/ incl. dotnet-provider.ts, .github/workflows/conformance.yml, the ASP.NET/EF Core backend A second messaging backend behind an abstraction seam. We have one Supabase backend and no reason for the seam.
Upstream src/services/messaging/message-service.ts as a file Diverged the opposite way from ours (provider seam + caches) vs. ours (RLS/fetch error discrimination, ensureKeys, query timeouts). Cherry-pick at most.
The "Machine Shop" / depth-token design system (.sh-btn, sh-doc, Archivo/Archivo Black, depth-tokens.spec.ts) This is ScriptHammer's brand identity, not a fix. We have spoketowork-dark / spoketowork-light. Read it as reference for #67; import nothing verbatim.
Blog/docs content, graphify hooks Content, not code. (The markdown-processor.ts fixes are separate and are worth taking — see below.)
Turnstile/CAPTCHA arc, Mailpit signup mailer, email-health.yml, auth-config-drift.yml, smoke.yml Real work, but tied to upstream's Supabase project config and mail identity. New features, not fixes to shared code.

✅ WE ARE AHEAD — do not "restore" these from upstream

Importing upstream here would be a regression:

  • eslint-plugin-no-secrets config, the gitleaks CI job, the pnpm audit + SQL-injection CI steps
  • deploy.yml gated on workflow_run: [CI] success
  • Storybook config (no staticDirs EEXIST bug, array-form alias ordering, mocked Auth/ActiveRoute contexts, guarded MSW init)
  • Vitest 4 with the 3-environment project split; Playwright 1.57; Node 22; actions/upload-pages-artifact@v4
  • tests/setup.ts Supabase mock harness
  • tests/e2e/utils/shard-users.ts + prebaked-keys.ts (upstream has no equivalent)
  • supabase/functions/delete-user-account/ (GDPR deletion — upstream lacks it)
  • CookieConsent buttons already at min-h-11 min-w-11
  • .gitleaks.toml — ours is stricter; cherry-pick only upstream's github_pat_ / sk_test_ rules

✔️ ALREADY DONE / NOTHING TO INHERIT


📥 Import candidates, ranked

Effort: XS = one line · S = under an hour · M = half a day · L = more

Tier 1 — take these

# What it fixes Upstream ref Our target Effort
1 Deploy serves HTML referencing assets that no longer exist → site renders with no CSS for ~10 min after each deploy scripts/retain-previous-assets.mjs + ASSET_MANIFEST step (#476) .github/workflows/deploy.yml M
2 .dockerignore — build context is ~1.19 GB upstream 101 lines vs our 48 .dockerignore S
3 Dead builder/runner Dockerfile stages that cannot build under output: 'export' ebbac6b docker/Dockerfile:69-99 XS
4 validate:breakpoints and test:coverage are defined but never invoked in CI .github/workflows/ci.yml XS
5 Component validator accepts empty test stubs (content.includes('test') vs 'test(') scripts/audit-components.js:277,301 XS
6 8 node:test files for the generator/validators already sit in our tree and are never executed test:scripts script package.json + ci.yml S
7 NEXT_PUBLIC_* stored as secrets. — masked in logs, unavailable to fork PRs all workflows S
8 Coverage exclude list (~50 entries) we dropped, which inflates the denominator with untestable route files vitest.config.ts S
9 generateId leaves a leading hyphen → every anchor on an emoji heading is broken 2b807ce src/lib/blog/markdown-processor.ts:270-278 XS
10 SpecKit: our .specify/ has no scripts/bash/, so the speckit.* slash commands have no scripts to call; constitution is v1.0.0 vs upstream v1.0.2 .specify/scripts/bash/* .specify/ S

Tier 2 — a11y / layout batch (feeds #70 and #67)

Upstream ran a large accessibility + typography sweep (their #373, #425, #428, #457, #473, #476, #479, #483, #495). Ours has the same defects because it has the same ancestor code.

# What it fixes Our target Effort
11 container capped at the previous breakpoint — up to 43% dead gutter on most pages src/app/globals.css @utility container XS + gate
12 html, body { overflow-x: hidden } breaks post-rotation width and makes the overflow gate unfailable src/app/globals.css:6-11, src/app/layout.tsx S
13 Overflow gate sweeps 2 of 39 routes and short-circuits to false tests/e2e/tests/mobile-horizontal-scroll.spec.ts, src/config/test-viewports.ts:204 S
14 sm: breakpoint fires at exactly 428px (iPhone 14/15 Pro Max) src/app/globals.css:16, src/config/breakpoints.ts:33,109 S
15 Sub-44px touch targets: CreateGroupModal.tsx:216 (btn-xs min-h-0 min-w-0 p-0), PWAInstall.tsx:256,263, GlobalNav.tsx:199,212,220, RouteCompanyList.tsx:142, TableHead.tsx:29, ModerationCard.tsx:56,69,91,98 various S
16 Touch-target gate measures ~1 element and reports green tests/e2e/tests/mobile-touch-targets.spec.ts S
17 AAA contrast sweep across all routes × both themes new tests/e2e/color-contrast.spec.ts M
18 Nav and footer inset differently at every width ≥ sm GlobalNav.tsx:169 XS

⚠️ Tier 2 will find real violations on first run. Budget for the fixes it surfaces, and land 12 and 13 together — removing the clip reveals overflow that the gate must be able to see.

Tier 3 — needs review before importing

# What Why careful
19 Messaging sequence-number / RLS integrity work, enforce_message_update_columns, is_conversation_{member,creator,owner} Upstream has 13 more RLS policies than us across 10 shared tables, concentrated on messages (-3) and conversations (-3). Per-policy audit, not a bulk copy. Overlaps #75.
20 custom_access_token_hook + is_admin() as the admin pattern We use set_own_role, a weaker pattern. Directly relevant to #75. Do not copy policies — port the pattern.
21 edge_idempotency_keys table We have webhook Edge Functions with no idempotency backing.
22 e2e browser de-serialization (needs: chain → max-parallel) Blocked. E2E_SHARD_INDEX is cut -d/ -f1 of matrix.shard, so all three browsers resolve to the same e2e-s1..s4-* users. The per-browser offset shard-users.ts:82 documents (chromium 1-4, firefox 5-8, webkit 9-12) was never implemented. Implement that first or the browsers collide.
23 pa11y adoption See #76 item 5 — decide adopt-or-delete first.

Reverse-import candidates (ours → upstream)

Worth offering back: the tests/setup.ts Supabase mock, shard-users.ts/prebaked-keys.ts, the delete-user-account Edge Function, our .gitleaks.toml + secret-scanning CI, storybook-audit.spec.ts + storybook-contrast-audit.spec.ts, and the workflow_run-gated deploy.


Method note

Because there is no shared history, the only reliable comparison is file-level. git -C ../ScriptHammer log --oneline --since=<date> gives the narrative; actual drift needs a diff of the specific file. Do not assume a same-named file is the same file — src/lib/manifest.ts is the cautionary example.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    documentationImprovements or additions to documentationenhancementNew feature or request

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions