Files
hanzo.ai/components/home/Observability.tsx

102 lines
4.9 KiB
TypeScript

'use client'
import { Fragment } from 'react'
import { ArrowRight } from 'lucide-react'
import { YStack, Text } from '@hanzo/ui'
import { Cta, Section } from '@/components/marketing/page-kit'
import { Chip, Run } from '@hanzo/ui/marketing'
/**
* The observability layer, stated as a flagship rather than a footnote.
*
* A company that runs on agents is a company whose work happens where nobody is
* looking. The claim is that the work is legible end to end, and the chain line
* IS the claim — one trace, from what was asked to what it cost.
*
* THE DETAIL LIVES ON /o11y. Eight cards used to stand here (one trace end to
* end · one store one query · every model call · every cost · sessions · scores
* and review · infrastructure underneath · dashboards and alerts), each read out
* of `hanzoai/o11y` before it was written. That is documentation, and the
* product page is where documentation belongs; /o11y states all eight in the
* same words, so the two cannot drift.
*
* WHAT THE SOURCE REFUSED, kept here because each was proposed once and will be
* proposed again: there is no dataset type, table, route or migration in o11y
* (`lib/data/catalog.json` lists one against /v1/evals/datasets — the code
* wins); experiment comparison is `hanzoai/insights`, a different product;
* "approvals" appear nowhere in o11y, the nearest real thing being an annotation
* queue with a PENDING status, which is post-hoc review; and `gen_ai.agent.*`
* exists only in a test fixture, so agent handoffs and model routing are not
* o11y's to claim — routing is Enso's.
*
* "Objective" in the lede is the page's own framing, set by the Enso section
* above. o11y's root span is a REQUEST and there is no objective entity behind
* it, so nothing downstream of this line may promise a company goal graph.
*
* One `Cta`, to /o11y, which is a real directory. The sub-products live at
* /cloud/<slug> behind a dynamic route, and a link that depends on a slug
* surviving in a generated catalog is a link that rots quietly. `/observability`
* is not a directory and must never be linked.
*/
/** The path one trace follows, in the order it is walked. */
const TRACE = ['Models', 'agents', 'tools', 'infrastructure', 'result', 'cost', 'evaluation']
export default function Observability() {
return (
<Section
title="See the whole company think."
lede="One trace connects the objective that started the work to everything that followed."
>
<YStack gap="$4">
{/* THE LEDE STOPPED NAMING THEM. It listed models, agents, tools,
services, infrastructure, cost, evaluation and outcome — the same
eight the chain below draws — so the section said its list twice and
the drawing was reduced to an illustration of the sentence above it.
The lede states what a trace IS; the chain is the evidence.
The trace, DRAWN. This was one bold line of prose whose separators
were already arrows — a chain written out as a sentence, in a page
that draws its layer stack with the same arrow one section up. Seven
steps a reader can count is the point of the claim above it; seven
words in a row is a claim about a picture nobody was shown.
Chips and not a grid, for the reason One system gives: each step is
as wide as its word, and equal tracks would pad `cost` out to the
width of `infrastructure` and turn a path into a table.
IT RUNS, because this one is genuinely ordered — the arrows are the
claim — so the `Run` steps near cycle/7 and the light walks the chain
rather than lifting all seven at once. A chip takes the even beats
and the arrow after it the odd one between, so the light crosses the
arrow on its way and the path is drawn rather than blinked.
Chip and arrow are FLAT siblings of the run, not a chip wrapped with
its arrow: the run animates its direct children, and a wrapper would
have taken the animation and passed nothing to the chip, whose border
is the thing that lights. */}
<Run step={0.31} flexDirection="row" flexWrap="wrap" items="center" gap="$2">
{TRACE.map((step, i) => (
<Fragment key={step}>
<Chip py={6} px={14} data-beat={2 * i}>
{step}
</Chip>
{i < TRACE.length - 1 ? (
<Text fontSize="$2" color="inherit" data-beat={2 * i + 1} aria-hidden>
→
</Text>
) : null}
</Fragment>
))}
</Run>
<Text render="p" fontSize="$3" color="$quiet" maxW={672}>
Logs, metrics, traces, sessions and scores share the same operational context.
</Text>
<Cta href="/o11y" icon={ArrowRight}>
Explore Observability
</Cta>
</YStack>
</Section>
)
}