Harden onion boot flow and deepen site surfaces

Add persistent onion key backup and restore, improve startup resilience, and flesh out the major site verticals with richer navigation, search coverage, and operator documentation.

Made-with: Cursor
This commit is contained in:
drjones
2026-04-07 21:35:52 -07:00
parent 52432dccfa
commit 78a071ba02
162 changed files with 21692 additions and 39 deletions

5
app/syndicate/layout.tsx Normal file
View File

@@ -0,0 +1,5 @@
import SyndicateSiteChrome from "@/components/syndicate/SyndicateSiteChrome";
export default function SyndicateLayout({ children }: { children: React.ReactNode }) {
return <SyndicateSiteChrome>{children}</SyndicateSiteChrome>;
}

33
app/syndicate/page.tsx Normal file
View File

@@ -0,0 +1,33 @@
import Link from "next/link";
import { SYNDICATE_NODES } from "@/lib/syndicateNetwork";
/** Index of themed `/w/[slug]` nodes — same Next app, different chrome. */
export default function SyndicateIndexPage() {
return (
<main>
<p className="mb-8 text-sm text-zinc-400">
Deep links:{" "}
<Link href="/syndicate/topology" className="text-fuchsia-400 underline hover:text-fuchsia-300">
topology
</Link>
{" · "}
<Link href="/syndicate/routing" className="text-fuchsia-400 underline hover:text-fuchsia-300">
routing lore
</Link>
</p>
<ul className="grid gap-3 sm:grid-cols-2">
{SYNDICATE_NODES.map((n) => (
<li key={n.slug}>
<Link
href={`/w/${n.slug}`}
className="block rounded-lg border border-zinc-800 bg-zinc-900/50 px-4 py-3 transition hover:border-fuchsia-500/40 hover:bg-zinc-900"
>
<span className="font-mono text-sm text-fuchsia-300">/{n.slug}</span>
<p className="mt-1 text-xs text-zinc-500">{n.tagline}</p>
</Link>
</li>
))}
</ul>
</main>
);
}

View File

@@ -0,0 +1,34 @@
import Link from "next/link";
export default function SyndicateRoutingPage() {
return (
<article className="space-y-8">
<header>
<h2 className="text-xl font-bold text-white md:text-2xl">Routing lore</h2>
<p className="mt-2 max-w-2xl text-sm text-zinc-400">
Dedicated onions rewrite paths to the correct vertical so bookmarks survive. This page names the behavior operators describe on status boards it mirrors how <code className="text-zinc-500">proxy.ts</code> reasons about roots, without dumping source.
</p>
</header>
<ul className="space-y-4 text-sm text-zinc-300">
<li className="rounded-lg border border-zinc-800 bg-zinc-900/40 p-4">
<strong className="text-fuchsia-200">Single build</strong> every hidden service serves the same compiled routes; differentiation is host-aware rewrites and disclosure chrome, not separate deploy artifacts per onion.
</li>
<li className="rounded-lg border border-zinc-800 bg-zinc-900/40 p-4">
<strong className="text-fuchsia-200">Canonical paths inside the app</strong> users still navigate to <code className="text-fuchsia-300/90">/w/slug</code> internally so relative links and prefetch stay coherent.
</li>
<li className="rounded-lg border border-zinc-800 bg-zinc-900/40 p-4">
<strong className="text-fuchsia-200">Cross-vertical links</strong> hub, market, and forum URLs in copy intentionally use absolute paths so they resolve correctly from any onion host after rewrite.
</li>
</ul>
<p className="text-xs text-zinc-500">
<Link href="/syndicate/topology" className="text-fuchsia-400 hover:underline">
Topology
</Link>
{" · "}
<Link href="/account/hidden-services" className="text-fuchsia-400 hover:underline">
Hidden services / mirrors
</Link>
</p>
</article>
);
}

View File

@@ -0,0 +1,33 @@
import Link from "next/link";
import { SYNDICATE_NODES } from "@/lib/syndicateNetwork";
export default function SyndicateTopologyPage() {
return (
<article className="space-y-8">
<header>
<h2 className="text-xl font-bold text-white md:text-2xl">Topology</h2>
<p className="mt-2 max-w-2xl text-sm text-zinc-400">
Three conceptual layers sit above the raw node list. Each <Link href="/syndicate" className="text-fuchsia-400 underline">shell</Link> inherits hub auth and cart paths; only chrome and copy diverge.
</p>
</header>
<ol className="list-decimal space-y-6 pl-5 text-sm text-zinc-300">
<li>
<strong className="text-fuchsia-200">Ingress</strong> Tor hostname maps to a dedicated root via proxy config; the browser still loads the same Next build.
</li>
<li>
<strong className="text-fuchsia-200">Presentation</strong> <code className="text-fuchsia-400/90">/w/[slug]</code> picks a skin;{" "}
<span className="font-mono text-fuchsia-300/80">{SYNDICATE_NODES.length} nodes</span> are registered in{" "}
<code className="text-zinc-500">syndicateNetwork</code>.
</li>
<li>
<strong className="text-fuchsia-200">Persistence</strong> forum posts, exchange rows, and cart JSON remain namespaced by origin in the usual browser model; operators document mirror bundles so users know which hostname they attached to.
</li>
</ol>
<p className="text-xs text-zinc-500">
<Link href="/syndicate/routing" className="text-fuchsia-400 hover:underline">
Routing lore
</Link>
</p>
</article>
);
}