mirror of
https://github.com/hanzo-apps/hanzo.ai.git
synced 2026-10-30 14:58:08 +00:00
The CLI lines on the product pages were written from the product name -- hanzo dns zones, hanzo kms keys -- and several were not commands the binary has. So the command moves into lib/product.ts, which assembles the rest from what is already stated: the catalog names the product and its route, pages.json names what the catalog does not carry, and products-metadata answers for docs, where null means docs publishes nothing and the link drops. Every CLI line in that table was run against the binary. A product absent from it has no command and its page prints none; nothing composes a verb out of a name. Both blocks that draw it import the Product type rather than declaring their own, which leaves the table the only place a command can be written. The catalog also moves out of package.json into pnpm-workspace.yaml, where pnpm reads it, so the versions are stated once.
80 lines
4.4 KiB
TypeScript
80 lines
4.4 KiB
TypeScript
'use client'
|
|
|
|
import { ArrowRight, AlertTriangle, Eye, Filter, Lock, Plug, ScrollText, Shield } from 'lucide-react'
|
|
import { ProductLanding } from '@/components/product/ProductLanding'
|
|
import { ProductFooter } from '@/components/products/ProductFooter'
|
|
|
|
/**
|
|
* Guard, through the ONE product kit.
|
|
*
|
|
* The largest cluster left: TWELVE pages — engine, gateway, guard, ingress,
|
|
* jin, metrics, o11y, operator, sentinel, skills, telemetry, visor — at 85%+
|
|
* identical className sets, each a hero, a six-card grid and a call to action
|
|
* written out again. All twelve pass one typed props object to
|
|
* `ProductLanding`. See LLM.md, "Tailwind is NOT gone".
|
|
*
|
|
* EVERY WORD IS THE ONE THAT WAS HERE. ProductFooter came out of the final
|
|
* card's `max-w-3xl` wrapper, where it had been rendering narrower than on
|
|
* every other product page.
|
|
*/
|
|
|
|
export default function GuardPage() {
|
|
return (
|
|
<>
|
|
<ProductLanding
|
|
badge={"hanzoai/guard"}
|
|
badgeIcon={Shield}
|
|
title={"Guard"}
|
|
tagline={"It reads what goes into a model, and what comes back"}
|
|
lede={"People paste their social security number into a chat box. Guard catches it on the way out and replaces it before the model ever sees it, then reads the reply on the way back. It runs three ways: as a proxy in front of an LLM API, as a wrapper around a command-line tool, or as a filter in front of an MCP server. A Rust library and a Unix pipe if you would rather not run a process at all."}
|
|
ctas={[
|
|
{ label: "View on GitHub", href: "https://github.com/hanzoai" },
|
|
]}
|
|
what={{
|
|
title: "What it looks for",
|
|
sub: "Detectors you can read, thresholds you can move, and no claim to understand meaning. Guard is the first layer, not the only one.",
|
|
pillars: [
|
|
{
|
|
icon: AlertTriangle,
|
|
title: "Six shapes an injection takes",
|
|
body: "Overriding the instructions, role-play, asking for the system prompt, bypassing a rule, hiding the ask in an encoding, and reframing the context. A match returns a confidence rather than a verdict, and you decide what confidence is worth blocking.",
|
|
},
|
|
{
|
|
icon: Lock,
|
|
title: "The things people paste by accident",
|
|
body: "Social security numbers, card numbers checked against the Luhn digit so a phone number is not mistaken for one, emails, phone numbers, IP addresses, and provider API keys. Each becomes a typed marker, so the model still knows a card number was there and does not lose the sentence.",
|
|
},
|
|
{
|
|
icon: Filter,
|
|
title: "Both directions, on purpose",
|
|
body: "The reply is read with the same detectors as the request, because the leak that matters is usually the one coming back. A machine-learning classifier for categories like violence and self-harm is available and off unless you turn it on — pattern matching is the default because it is the part that behaves the same every time.",
|
|
},
|
|
{
|
|
icon: ScrollText,
|
|
title: "You set the dials",
|
|
body: "Turn each detector on or off, set the injection threshold, add your own patterns for whatever is sensitive in your domain, and choose the marker text. Requests are rate limited per user with a token bucket, so a single caller cannot burn the budget.",
|
|
},
|
|
{
|
|
icon: Eye,
|
|
title: "A log that is not a second copy of the leak",
|
|
body: "Decisions are written as JSON lines with a hash of the content, not the content. Logging what you just redacted would put it in a file with weaker access control than the one you took it out of. Turn content logging on deliberately, or leave it off.",
|
|
},
|
|
{
|
|
icon: Plug,
|
|
title: "Nothing to rewrite",
|
|
body: "Start the proxy with your provider as the upstream and point the base URL at it. Or wrap a CLI tool over a pseudo-terminal and everything you type is filtered on its way in. Or put it in front of an MCP server and filter the tool calls.",
|
|
},
|
|
],
|
|
}}
|
|
finalCta={{
|
|
title: "Get started with Guard",
|
|
buttons: [
|
|
{ label: "View on GitHub", href: "https://github.com/hanzoai" },
|
|
],
|
|
}}
|
|
/>
|
|
<ProductFooter slug={"guard"} name={"Guard"} />
|
|
</>
|
|
)
|
|
}
|