Skip to content

feat(ghostkey): make the vault findable, and keep it off try.freenet.org - #189

Open
sanity wants to merge 4 commits into
mainfrom
ghostkey-vault-open
Open

sanity wants to merge 4 commits into
mainfrom
ghostkey-vault-open

Conversation

@sanity

@sanity sanity commented Sep 28, 2026 •

Copy link
Copy Markdown
Contributor

The Ghost Key vault was only linked from low on /ghostkey/ and from the donation success page, both as raw localhost:7509 links that dead-end for anyone without a running peer. The success page even said "nothing else links to it".

Changes

  • /ghostkey/ hero: "Already have one? Open your vault".
  • The /ghostkey/ vault button and the Apps page Ghost Keys entry now go through /open/#<vault id>/, so a visitor without a peer gets "Get Freenet" instead of a dead link.
  • /open gains a LOCAL_ONLY list (currently just the vault's web container id). For those ids, "Use in your browser" is replaced by a note: try.freenet.org is for trying Freenet out, and a Ghost Key kept there lives on a peer we host. /ghostkey/ now says the same, and the Share Links manual page documents the exception.
  • Unchanged on purpose: "Import to Freenet" on the success page stays a direct localhost link. Its fragment carries the signing key, and routing it through /open would put a one-click "import on try.freenet.org" in front of the donor.
  • The success page no longer claims nothing else links to the vault.
  • /open's "Open in Freenet" button is hidden until a release registers freenet: links. No release does yet (freenet-core#5753 merged after 0.2.139 was cut), so it only produced "No apps available" for a 0.2.139 user. It is display: none rather than removed, so the JS still builds its href and the vector test still checks it; the comment above it says how to re-enable. Managed installs self-register the handler at node start once a release carries it.
  • scripts/check-links.py: /open's fragment is a share link, not an anchor, so /open/#<id>/ links were flagged as dead anchors (the first CI run failed on exactly that). /open/ is now exempt (the page must still exist), with self-test cases showing /open is exempt and other pages are not; emptying the exemption makes the self-test fail.
  • Corrected the stale comment in donation-success.js claiming the node serves only the IPv6 loopback (freenet-core#4332 serves both).

Verification

  • node hugo-site/tests/open-link-vectors.test.mjs: 57 shared vectors plus new local-only cases (vault hides the try option and shows the note; a hashchange back to an ordinary id restores the button). Removing the vault entry makes the new cases fail (2 failures), so the check can go red.
  • hugo build is clean. Checked in Chromium: clicked "Open your vault" from /ghostkey/, and /open showed no try button and showed the note; a hashchange to another id brought the button back. Screenshots checked in light and dark mode and at 390px width.

Caveat: LOCAL_ONLY is keyed by the vault's contract id, so a ghostkeys re-key must update it, along with the other hard-coded copies of that id on this site.

[AI-assisted - Claude]

https://claude.ai/code/session_011kgp91jp3UiWjo5eHAQfyq

The Ghost Key vault was linked only from low on /ghostkey/ and from the
donation success page, both as raw localhost links that dead-end for
anyone without a running peer.

- /ghostkey/ hero: "Already have one? Open your vault".
- /ghostkey/ vault button and the Apps page entry now go through
  /open, so a visitor without a peer gets "Get Freenet" instead of a
  dead link. The import button stays a direct localhost link: its
  fragment carries the signing key.
- /open gains a LOCAL_ONLY list. For the vault it replaces "Use in your
  browser" with a note: try.freenet.org is for trying Freenet out, and
  a Ghost Key kept there lives on a peer we host. /ghostkey/ says the
  same. Tested, including a hashchange back to an ordinary id.
- Success page no longer claims nothing else links to the vault.
- Correct the stale IPv6-only comment in donation-success.js
  (freenet-core#4332 serves both loopbacks).

Claude-Session: https://claude.ai/code/session_011kgp91jp3UiWjo5eHAQfyq
"Needs a Freenet release newer than 0.2.139" read as "0.2.139 or later":
a 0.2.139 user clicked "Open in Freenet" and got "No apps available".
The handler (freenet-core#5753) merged after 0.2.139 was cut, so no
release has it yet.

Claude-Session: https://claude.ai/code/session_011kgp91jp3UiWjo5eHAQfyq
No Freenet release registers freenet: links yet (freenet-core#5753 merged
after 0.2.139 was cut), so the button only produced "no app can open this
link". Hidden with display:none rather than removed, so the page JS still
fills in its href and the shared-vector test still checks it; the comment
above it says how to re-enable. Its note is reworded to be correct on the
day it comes back.

check-links: /open's fragment is a share link its JS reads, not an anchor,
so links to /open/#<id>/ were reported as dead anchors. Exempt that one
page (it must still exist), with self-test cases proving /open is exempt
and other pages are not.

Claude-Session: https://claude.ai/code/session_011kgp91jp3UiWjo5eHAQfyq
Review of #189: the exemption was checked only on the linked page, so an
alias that redirects to /open would have had its share-link fragment
flagged as a dead anchor. Check the redirect target as well; self-test
case added (fails with the check removed).

Claude-Session: https://claude.ai/code/session_011kgp91jp3UiWjo5eHAQfyq
@sanity

sanity commented Sep 28, 2026

Copy link
Copy Markdown
Contributor Author

Review (Light tier, independent Claude reviewers)

  • Round 1, on 9e8d235f + 08ce4214: skeptical/code-first lens and big-picture/user-facing lens. No blocking or should-fix findings. One nit: [try.freenet.org](/try/) links the explainer page rather than the domain. Kept on purpose, since /try/ explains what the hosted peer is.
  • Round 2, adversarial read of 08ce4214..8002c0e9 (hidden "Open in Freenet" button, check-links exemption): one should-fix. The exemption was checked only on the linked page, not on a redirect target, so an alias of /open would have been flagged falsely. Fixed in 81bdb2d2, with a self-test case that fails when the check is removed.
  • No external model pass: Light tier, and no high-risk surface.

CI green at 81bdb2d2: build (including check-links), vectors, CLA.

[AI-assisted - Claude]

This branch has not been deployed

No deployments
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