Skip to content

feat(identity): delete accounts and publish a privacy page - #248

Merged
harlan-zw merged 5 commits into
mainfrom
feat/account-deletion-privacy
Sep 22, 2026
Merged

harlan-zw merged 5 commits into
mainfrom
feat/account-deletion-privacy

Conversation

@harlan-zw

@harlan-zw harlan-zw commented Sep 16, 2026 •

Copy link
Copy Markdown
Collaborator

Rebased onto main now that #241 has landed. The old base branch was merged, so the diff read against a dead ref.

❓ Type of change

  • ✨ New feature

📚 Description

Nobody could delete a skilld account, and nothing on skilld.dev said what the site stores. This adds both.

Account deletion. /me gets a Delete account section. The confirm dialog asks for the GitHub login. DELETE /api/me also needs the sign-in cookie: a CLI token alone gets a 403, so a token copied off a laptop cannot delete the account. One D1 batch removes every row that names the account. Then the Worker asks GitHub to revoke the OAuth grant and clears the session. If GitHub refuses or times out, the account is still gone and the toast links to GitHub settings.

Decisions I made:

  • Skills from the person's public Repositories stay. GitHub is their source, and discovery would index them again anyway. owners and skill_revisions.author_login stay for the same reason.
  • Collections, likes, watches, and imported stars go. Likes and collection entries feed Skill counters, so the affected Skills join skill_dirty for a recount.
  • Every account table gets its own delete, cascade or not. email_preference_events has no foreign key, so deleting the users row alone would leave rows behind.
  • GitHub App rows are only deleted locally. The App installation and its user authorization stay on GitHub, and private Artifact ciphertext stays in R2 without its account keys. Private delivery is off in production, so GitHub-side cleanup waits for when it ships.

/privacy is a Markdown article like /verify, linked from the footer and from the delete section. It now describes the site as it actually works, including the parts that exist to grow it:

  • Anonymous usage counts. A copied command records the surface, the grammar, the Skill, and the country in Cloudflare Analytics Engine for 90 days. No IP address, no cookie, no account ID, and no record of an individual copy.
  • Cloudflare Web Analytics through the same-origin proxy, and timing traces on 1 request in 100.
  • Aggregate email click counts, including the links to GitHub, which are counted by Repository.
  • The defaults for liked Skills and Repository indexing, both on with a switch in /me.

Merge this last, after #240, #243, and #244. /privacy describes the site once they land.

Loose ends:

🤖 AI disclosure: Harlan Agent Kit modified this description. My AI open-source policy.

@harlan-zw

Copy link
Copy Markdown
Collaborator Author

Checked by hand, since CI cannot cover it:

  • Deleted a seeded account through the dashboard on nuxi dev with a local D1. DELETE /api/me returned 200 with github_access_revoked: false, because the account had no stored token. Its user, like, watch, collection, collection entry, CLI token, and email preference rows were gone. skill_dirty gained acme/skills/diagnose (like) and acme/skills/tdd (curator). The browser lost its session cookie and landed on the home page with the GitHub settings toast.
  • The confirm button stayed disabled for demo-de and turned on for Demo-Dev.
  • A production build preview set __nkpv with Max-Age=604800 on a document request, and nuxt-session with no expiry, HttpOnly, and SameSite=Lax. Those match the cookie list on /privacy.
  • Production wide events carry cf.country and cf.colo, so /privacy says request logs hold your country and the data center.
Delete account section Confirm dialog
Delete account section on /me Confirm dialog with the login typed

Home page after deletion, with the GitHub settings toast

/privacy, desktop /privacy, mobile
Top of the privacy page on desktop Top of the privacy page on mobile

Delete your account section of the privacy page

@harlan-github-agent harlan-github-agent Bot added harlan-agent-running An Agent holds a Task on this issue or pull request right now. harlan-agent-review-required Pull request triage requires an adversarial Review for this head commit. labels Sep 16, 2026
@harlan-github-agent

harlan-github-agent Bot commented Sep 16, 2026 •

Copy link
Copy Markdown
Contributor

🤖 MERGED

Harlan Agent Kit posted this automated review. It is not Harlan's personal review or approval. AI open source policy. Last updated: 2026-09-22 07:02 UTC.

GitHub merged this pull request.

No material findings were recorded.

22de60c4-00c2-45fa-ad70-eb09cd953593

@harlan-github-agent harlan-github-agent Bot added harlan-agent-running An Agent holds a Task on this issue or pull request right now. harlan-agent-ready The automated Review passed every gate on this head commit. harlan-agent-pending The automated Review is waiting on a gate for this head commit. and removed harlan-agent-running An Agent holds a Task on this issue or pull request right now. harlan-agent-review-required Pull request triage requires an adversarial Review for this head commit. harlan-agent-ready The automated Review passed every gate on this head commit. harlan-agent-pending The automated Review is waiting on a gate for this head commit. labels Sep 16, 2026
Nobody could remove a skilld account or the data tied to it. Several
account tables carry no foreign key, so deleting the users row alone would
leave email history and tokens behind.

The test reads the migrated schema. A future table that names an account
fails it until account deletion clears that table too.
skilld.dev had no page that says what it stores, why, and for how long.
The page describes the site after #240 and #241 and explains how to
delete an account.
The page described the site after #240 and #241 only. #242, #243, #244,
and #246 change CLI token labels, email click counts, like visibility,
repository indexing, and image loading, and D1 recovery keeps deleted rows
for up to 30 days.
The owner keeps Web Analytics on, so the page no longer claims skilld.dev runs no analytics. It lists what Cloudflare documents the beacon records.
/privacy described a site with no usage analytics. skilld.dev keeps anonymous
counts of copied commands, because it needs to know which Skills people run.
The page now says what a count holds, where it lives, and how long it stays,
plus the 1% timing traces, the counted GitHub links in email, and the new
defaults for liked Skills and Repository indexing.
@harlan-zw
harlan-zw force-pushed the feat/account-deletion-privacy branch from 16268dd to 4c4d860 Compare September 22, 2026 02:32
@harlan-zw
harlan-zw changed the base branch from chore/privacy-data-retention to main September 22, 2026 02:32
@harlan-github-agent harlan-github-agent Bot added harlan-agent-running An Agent holds a Task on this issue or pull request right now. and removed harlan-agent-ready The automated Review passed every gate on this head commit. labels Sep 22, 2026
@harlan-github-agent harlan-github-agent Bot added harlan-agent-running An Agent holds a Task on this issue or pull request right now. harlan-agent-ready The automated Review passed every gate on this head commit. and removed harlan-agent-running An Agent holds a Task on this issue or pull request right now. labels Sep 22, 2026
@harlan-zw
harlan-zw merged commit 5e7abe0 into main Sep 22, 2026
6 checks passed
@harlan-github-agent harlan-github-agent Bot removed the harlan-agent-ready The automated Review passed every gate on this head commit. label Sep 22, 2026
@harlan-zw
harlan-zw deleted the feat/account-deletion-privacy branch September 22, 2026 07:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant