Files
krow_talent_app/scripts/__baseline__/analytics.render.html
Aravind 878a23532a test(baseline): recapture the three HTML baselines that held invented people
Commit A of the baseline remediation. The Owliver baseline is deliberately
untouched and is Commit B.

Five of the six failing checks were the `DEMO_FILL` removal. `hiringRecords`
used to pad the hires list with five invented people so Hired History read
as a history rather than as three rows, and the padding reached Analytics
too, where "total hires" counted eight against a database holding three.
Because these baselines render with queries disabled, the padding was ALL
they contained. The sixth is Candidates becoming the final-selection queue,
which changed what its empty state says.

Verified before regenerating rather than after. Hired History's tag counts,
baseline -> now: `<td` 40->0, `<span` 51->13, `<div` 78->39, `<p` 26->7,
`<svg` 20->8. Analytics lost 269 class attributes and 238 words to the same
cause; Candidates gained exactly one class, the description paragraph under
"Nobody is awaiting a decision". Every generated file was checked for the
five invented names (none), for the intended new copy (present) and for its
node identities before it was put in place.

Renamed, because a file called `pre-migration` holding post-`dca1842`
markup is a lie in the filename. `activity-page`, `candidates-analysis`,
`control-center`, `positions` and `talent-pool` still hold genuine
pre-migration markup, still pass, and keep the name that says so — so the
`PAGES` table now carries each baseline's FILENAME rather than deriving one
suffix for all five.

The migration proof was replaced, not discarded. `Hired History added only
identity wrappers` compared tag tallies to assert that migrating the page
added exactly two `<div>`s and changed nothing else. That was true, and it
was checkable only while the DATA was frozen as well: the predicate
subtracts one render from another, so removing the invented hires moved
every count and the arithmetic stopped describing wrappers. Recapturing
would not have rescued it — with the baseline equal to the render the delta
is zero and a predicate demanding two can never hold — so left in place it
would have stayed red for a new reason. Three checks read the render
directly instead and need no frozen file:

    Hired History wraps exactly the node types registered to wrap
    Hired History identities are unique and name composed nodes
    Hired History identity wrappers carry no styling

They say what the tally said: `UiTreeRenderer` encloses a type registered
`wrap: true` in `<div {...attrs}>`, every other type takes the attributes on
its own root element, and a wrapper carries identity and no styling.

Writing them first, against the OLD baseline, is what caught my own error:
the second check began as "one identity per composed node" and failed at
4 of 5. Hired History composes five nodes and `hired-extensions-top` is an
extension slot that renders nothing while no skill is attached to it, so a
one-to-one rule would have asserted that every slot is always filled. It
asserts uniqueness and no strays instead — a node addressed twice, or an
identity naming nothing the page composed, would break the editor's and
Owliver's ability to name a node. Had the baselines been recaptured first,
that mistake would have been invisible.

`carries node identity in the DOM` was documented as needing pre-migration
markup. It does not — it reads only the live render — so it is unchanged and
still passes. The dead `tally` helper is removed with its last caller.

  typecheck   0 errors
  lint        exit 0, 0 errors, 289 warnings
  npm test    1693/1693, exit 0 — was 1685/1691
  build       exit 0, bundle 74d17e2d… unchanged
  owliver     still DRIFTED — that is Commit B, untouched here

No file under `src/` changed, which is why the bundle hash cannot move.
`owliver-baseline.json` is byte-identical, the backend is untouched, and CI
configuration is unchanged. The suite total rises 1691 -> 1693 because one
assertion became three; CI asserts `passed == total` and a floor of 900,
both satisfied.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HBG1wnuRfJKCstGB8Fekr8
2026-09-20 00:52:53 +05:30

1 line
14 KiB
HTML

<div class="space-y-6"><header class="flex flex-wrap items-center justify-between gap-4 border-b border-border/50 pb-4"><div class="min-w-0 space-y-1"><div class="flex flex-wrap items-center gap-x-2.5 gap-y-1.5"><h1 class="font-heading text-title-lg font-bold tracking-tight text-ink-1 sm:text-2xl">Analytics</h1><span class="inline-flex shrink-0 items-center gap-1.5 whitespace-nowrap rounded-full bg-blue-50 px-2.5 py-0.5 text-[11px] font-semibold text-blue-600 dark:bg-blue-950/60 dark:text-blue-400 border border-blue-200/60 dark:border-blue-800/40"><span class="h-1.5 w-1.5 rounded-full bg-blue-600 dark:bg-blue-400"></span>Live System</span></div><p class="text-body-sm text-ink-3 font-normal">How hiring is performing — rates, trends, comparison and what to act on.</p></div></header><section aria-labelledby="performance" class="space-y-3" data-ui-node="performance" data-ui-type="analytics-performance"><div class="flex flex-wrap items-baseline justify-between gap-2"><div class="flex min-w-0 flex-wrap items-baseline gap-x-2"><h2 id="performance" class="font-heading text-body font-semibold text-ink-1">Hiring performance</h2><span class="text-caption text-ink-4">Across the workspace</span></div></div><div class="grid gap-3.5 grid-cols-2 sm:grid-cols-4"><div class="group relative flex flex-col justify-between rounded-xl border border-border/80 bg-surface p-4 shadow-xs backdrop-blur-xs transition-all duration-200 hover:-translate-y-0.5 hover:shadow-md hover:border-blue-500/40"><div><div class="flex items-center justify-between gap-1.5"><p class="min-w-0 line-clamp-2 text-[10px] font-bold uppercase tracking-wider text-ink-4 sm:line-clamp-1">Total hires</p><div class="flex h-7 w-7 shrink-0 items-center justify-center rounded-lg shadow-xs bg-blue-50 text-blue-600 dark:bg-blue-950/60 dark:text-blue-400"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-award h-3.5 w-3.5" aria-hidden="true"><path d="m15.477 12.89 1.515 8.526a.5.5 0 0 1-.81.47l-3.58-2.687a1 1 0 0 0-1.197 0l-3.586 2.686a.5.5 0 0 1-.81-.469l1.514-8.526"></path><circle cx="12" cy="8" r="6"></circle></svg></div></div><div class="mt-2 flex flex-wrap items-baseline gap-2"><span class="font-heading font-bold leading-none tabular-nums text-blue-600 dark:text-blue-400">0</span></div></div><div class="mt-3.5 space-y-2"><div class="h-0.5 w-full rounded-full bg-gradient-to-r opacity-40 group-hover:opacity-100 transition-opacity from-blue-500 to-indigo-500"></div></div></div><div class="group relative flex flex-col justify-between rounded-xl border border-border/80 bg-surface p-4 shadow-xs backdrop-blur-xs transition-all duration-200 hover:-translate-y-0.5 hover:shadow-md hover:border-blue-500/40"><div><div class="flex items-center justify-between gap-1.5"><p class="min-w-0 line-clamp-2 text-[10px] font-bold uppercase tracking-wider text-ink-4 sm:line-clamp-1">Avg time-to-hire</p><div class="flex h-7 w-7 shrink-0 items-center justify-center rounded-lg shadow-xs bg-surface-subtle text-ink-3"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-clock h-3.5 w-3.5" aria-hidden="true"><circle cx="12" cy="12" r="10"></circle><polyline points="12 6 12 12 16 14"></polyline></svg></div></div><div class="mt-2 flex flex-wrap items-baseline gap-2"><span class="font-heading font-bold leading-none tabular-nums text-ink-1">—</span></div></div><div class="mt-3.5 space-y-2"><div class="h-0.5 w-full rounded-full bg-gradient-to-r opacity-40 group-hover:opacity-100 transition-opacity from-gray-400 to-gray-600"></div></div></div><div class="group relative flex flex-col justify-between rounded-xl border border-border/80 bg-surface p-4 shadow-xs backdrop-blur-xs transition-all duration-200 hover:-translate-y-0.5 hover:shadow-md hover:border-blue-500/40"><div><div class="flex items-center justify-between gap-1.5"><p class="min-w-0 line-clamp-2 text-[10px] font-bold uppercase tracking-wider text-ink-4 sm:line-clamp-1">Quality of hire</p><div class="flex h-7 w-7 shrink-0 items-center justify-center rounded-lg shadow-xs bg-surface-subtle text-ink-3"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-trending-up h-3.5 w-3.5" aria-hidden="true"><polyline points="22 7 13.5 15.5 8.5 10.5 2 17"></polyline><polyline points="16 7 22 7 22 13"></polyline></svg></div></div><div class="mt-2 flex flex-wrap items-baseline gap-2"><span class="font-heading font-bold leading-none tabular-nums text-ink-1">—</span></div></div><div class="mt-3.5 space-y-2"><span class="inline-flex items-center rounded-full bg-surface-subtle px-2 py-0.5 text-[10px] font-semibold text-ink-3 border border-border/60">avg AI score</span><div class="h-0.5 w-full rounded-full bg-gradient-to-r opacity-40 group-hover:opacity-100 transition-opacity from-gray-400 to-gray-600"></div></div></div><div class="group relative flex flex-col justify-between rounded-xl border border-border/80 bg-surface p-4 shadow-xs backdrop-blur-xs transition-all duration-200 hover:-translate-y-0.5 hover:shadow-md hover:border-blue-500/40"><div><div class="flex items-center justify-between gap-1.5"><p class="min-w-0 line-clamp-2 text-[10px] font-bold uppercase tracking-wider text-ink-4 sm:line-clamp-1">Conversion rate</p><div class="flex h-7 w-7 shrink-0 items-center justify-center rounded-lg shadow-xs bg-surface-subtle text-ink-3"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-target h-3.5 w-3.5" aria-hidden="true"><circle cx="12" cy="12" r="10"></circle><circle cx="12" cy="12" r="6"></circle><circle cx="12" cy="12" r="2"></circle></svg></div></div><div class="mt-2 flex flex-wrap items-baseline gap-2"><span class="font-heading font-bold leading-none tabular-nums text-ink-1">0%</span></div></div><div class="mt-3.5 space-y-2"><span class="inline-flex items-center rounded-full bg-surface-subtle px-2 py-0.5 text-[10px] font-semibold text-ink-3 border border-border/60">0 of 0 applicants</span><div class="h-0.5 w-full rounded-full bg-gradient-to-r opacity-40 group-hover:opacity-100 transition-opacity from-gray-400 to-gray-600"></div></div></div></div></section><section aria-labelledby="funnel" class="space-y-3" data-ui-node="funnel" data-ui-type="analytics-funnel"><div class="flex flex-wrap items-baseline justify-between gap-2"><div class="flex min-w-0 flex-wrap items-baseline gap-x-2"><h2 id="funnel" class="font-heading text-body font-semibold text-ink-1">Hiring funnel</h2><span class="text-caption text-ink-4">Applied → Screened → Shortlisted → Interview → Hired</span></div></div><div class="transition-all duration-base ease-out bg-surface shadow-xs rounded-xl p-6 border border-border"><p class="text-body-sm leading-relaxed text-ink-3">No applications on file yet. The funnel appears once the first candidate applies.</p></div></section><section aria-labelledby="trend" class="space-y-3" data-ui-node="trend" data-ui-type="analytics-trend"><div class="flex flex-wrap items-baseline justify-between gap-2"><div class="flex min-w-0 flex-wrap items-baseline gap-x-2"><h2 id="trend" class="font-heading text-body font-semibold text-ink-1">Hiring trend</h2><span class="text-caption text-ink-4">Cumulative hires by month</span></div></div><div class="overflow-hidden rounded-xl border border-border bg-surface"><div class="px-4 py-8 text-center"><p class="font-heading text-body font-semibold text-ink-1">Not enough history for a trend</p><p class="mx-auto mt-1 max-w-md text-body-sm leading-relaxed text-ink-3">No hires recorded yet. Hiring volume over time appears here once the first role closes.</p></div></div></section><section aria-labelledby="departments" class="space-y-3" data-ui-node="departments" data-ui-type="analytics-departments"><div class="flex flex-wrap items-baseline justify-between gap-2"><div class="flex min-w-0 flex-wrap items-baseline gap-x-2"><h2 id="departments" class="font-heading text-body font-semibold text-ink-1">Department performance</h2><span class="text-caption text-ink-4">0 departments compared</span></div></div></section><section aria-labelledby="positions" class="space-y-3" data-ui-node="positions" data-ui-type="analytics-positions"><div class="flex flex-wrap items-baseline justify-between gap-2"><div class="flex min-w-0 flex-wrap items-baseline gap-x-2"><h2 id="positions" class="font-heading text-body font-semibold text-ink-1">Position performance</h2><span class="text-caption text-ink-4">0 roles filled</span></div></div><div class="transition-all duration-base ease-out bg-surface shadow-xs rounded-xl p-0 overflow-hidden border border-border"><div class="overflow-x-auto"><table class="w-full min-w-[36rem] border-collapse text-body-sm"><caption class="sr-only">Hires, quality, speed and review outcome by role</caption><thead><tr class="border-b border-border bg-surface-subtle"><th scope="col" class="whitespace-nowrap px-3.5 py-2.5 text-[10px] font-bold uppercase tracking-wider text-ink-4 text-left">Role</th><th scope="col" class="whitespace-nowrap px-3.5 py-2.5 text-[10px] font-bold uppercase tracking-wider text-ink-4 text-right">Hires</th><th scope="col" class="whitespace-nowrap px-3.5 py-2.5 text-[10px] font-bold uppercase tracking-wider text-ink-4 text-right">Avg score</th><th scope="col" class="whitespace-nowrap px-3.5 py-2.5 text-[10px] font-bold uppercase tracking-wider text-ink-4 text-right">Avg days</th><th scope="col" class="whitespace-nowrap px-3.5 py-2.5 text-[10px] font-bold uppercase tracking-wider text-ink-4 text-right">Reviewed</th><th scope="col" class="whitespace-nowrap px-3.5 py-2.5 text-[10px] font-bold uppercase tracking-wider text-ink-4 text-right">Rating</th></tr></thead><tbody class="divide-y divide-border"></tbody></table></div></div></section><section aria-labelledby="efficiency" class="space-y-3" data-ui-node="efficiency" data-ui-type="analytics-efficiency"><div class="flex flex-wrap items-baseline justify-between gap-2"><div class="flex min-w-0 flex-wrap items-baseline gap-x-2"><h2 id="efficiency" class="font-heading text-body font-semibold text-ink-1">Hiring efficiency</h2><span class="text-caption text-ink-4">Not enough dated hires</span></div></div><div class="grid grid-cols-1 gap-4 lg:grid-cols-3"><div class="transition-all duration-base ease-out bg-surface shadow-xs rounded-xl p-6 border border-border"><div class="flex items-center gap-2 text-krow-blue"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-gauge h-4 w-4" aria-hidden="true"><path d="m12 14 4-4"></path><path d="M3.34 19a10 10 0 1 1 17.32 0"></path></svg><h3 class="font-heading text-body-sm font-bold text-ink-1">Velocity</h3></div><p class="mt-2 font-heading text-title font-bold tabular-nums text-ink-1">—<span class="ml-1.5 text-caption font-normal text-ink-3">median</span></p><p class="mt-1 text-caption leading-relaxed text-ink-3">Velocity appears once hires carry an application date.</p></div><div class="transition-all duration-base ease-out bg-surface shadow-xs rounded-xl p-6 border border-border"><div class="flex items-center gap-2 text-emerald-600 dark:text-emerald-400"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-activity h-4 w-4" aria-hidden="true"><path d="M22 12h-2.48a2 2 0 0 0-1.93 1.46l-2.35 8.36a.25.25 0 0 1-.48 0L9.24 2.18a.25.25 0 0 0-.48 0l-2.35 8.36A2 2 0 0 1 4.49 12H2"></path></svg><h3 class="font-heading text-body-sm font-bold text-ink-1">Fastest to fill</h3></div><div class="mt-3"><p class="rounded-lg border border-dashed border-border px-3 py-3 text-body-sm text-ink-3">No role has enough dated hires to measure velocity yet.</p></div></div><div class="transition-all duration-base ease-out bg-surface shadow-xs rounded-xl p-6 border border-border"><div class="flex items-center gap-2 text-amber-600 dark:text-amber-400"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-clock h-4 w-4" aria-hidden="true"><circle cx="12" cy="12" r="10"></circle><polyline points="12 6 12 12 16 14"></polyline></svg><h3 class="font-heading text-body-sm font-bold text-ink-1">Slowest to fill</h3></div><div class="mt-3"><p class="rounded-lg border border-dashed border-border px-3 py-3 text-body-sm text-ink-3">No role has enough dated hires to measure velocity yet.</p></div></div></div></section><section aria-labelledby="insights" class="space-y-3" data-ui-node="insights" data-ui-type="analytics-insights"><div class="flex flex-wrap items-baseline justify-between gap-2"><div class="flex min-w-0 flex-wrap items-baseline gap-x-2"><h2 id="insights" class="font-heading text-body font-semibold text-ink-1">AI hiring insights</h2></div></div><div class="transition-all duration-base ease-out bg-surface shadow-xs rounded-xl p-6 border border-border"><p class="text-body-sm leading-relaxed text-ink-3">There is not enough hiring on file to draw a finding from yet. Insights appear as applications, hires and reviews accumulate.</p></div></section></div>