Move the landing page and docs into one Next.js site, ready for launch - #10
Merged
Merged
Conversation
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Also update the spec's sequencing: the uncommitted Vite landing work is the port source and is deleted once site/ serves both pages. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LdnJCJHVx2mfpfoHi6pbqG
Creates site/ as a standalone Next.js 16.3.6 + Turbopack package with its own package.json/pnpm-lock.yaml (joins no workspace), vitest wired up, and an MDX component map. Proves the plan's one open risk: importing brand SVGs from the repo's docs/assets/brand/ across the site root resolves correctly under Turbopack (widened turbopack.root + outputFileTracingRoot), verified by a production build that emits a content-hashed oap-wordmark-light SVG. pnpm add hit ERR_PNPM_IGNORED_BUILDS for core-js and esbuild (not sharp, as the brief anticipated, but the same pnpm build-approval gate); added site/pnpm-workspace.yaml with allowBuilds for sharp/esbuild/core-js to unblock install, following the same key showcase/pnpm-workspace.yaml uses. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LdnJCJHVx2mfpfoHi6pbqG
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LdnJCJHVx2mfpfoHi6pbqG
Relocates the 129 MDX guides, refs sidecars, manifest, and media from showcase/docs into site/content and site/public so the new Next.js site owns its content directly. Points the checker (now `pnpm check` in site/) and the Go docs generators (magefiles/clidocs.go) at the new location. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LdnJCJHVx2mfpfoHi6pbqG
Ports the docs chrome from the Vite app in showcase/docs/app into site/: root layout wired to next-themes (data-theme attribute, dark/light/system, icons, viewport theme-color), the sidebar/nav/article components (Wordmark, NavLink, ThemeToggle, media, Callout, Coverage), the docs.css chrome scoped to .doc-app rather than the whole document, and the /docs and /docs/[slug] routes with generateStaticParams over all 129 guides. Adds linkKind() to classify MDX anchors as docs/external/plain and wires it into mdx-components.tsx. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LdnJCJHVx2mfpfoHi6pbqG
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LdnJCJHVx2mfpfoHi6pbqG
Copies Landing.tsx, landing.css and OapMark.tsx from the Vite showcase app into site/app/(landing)/, rewrites the hash-route docs links to real /docs/<slug> paths, extracts the OWASP coverage table into owasp.ts, and pins its templated anchor hrefs with owasp.test.ts against content/docs/owasp-top10.mdx. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LdnJCJHVx2mfpfoHi6pbqG
Adds a loader/URL helper (site/lib/pagefind.ts) that dynamically imports the Pagefind bundle written to public/_pagefind by `pnpm build`, guarded against Turbopack/webpack resolution via inline ignore comments since the bundle doesn't exist at compile time. Mounts a client Search component in the docs sidebar, right after the brand row, that falls back to a "search is available after pnpm build" note under `next dev`. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LdnJCJHVx2mfpfoHi6pbqG
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LdnJCJHVx2mfpfoHi6pbqG
posthogOptions is a pure options function: it initializes only when a key is set and NEXT_PUBLIC_VERCEL_ENV is "production", with cookieless_mode, person_profiles: never, and every replay/heatmap/survey/flag capture disabled. Analytics.tsx calls it once from the root layout. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LdnJCJHVx2mfpfoHi6pbqG
They were previously inert only as a side effect of advanced_disable_flags and disable_external_dependency_loading; pin them directly so a future SDK change can't silently re-enable a chat/tour widget. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LdnJCJHVx2mfpfoHi6pbqG
The Next.js site/ app now serves both the landing page and the docs (Tasks 4-8), so the old Vite docs app in showcase/docs/ is no longer needed. Deletes it along with vite.docs.config.ts, drops the docs-only scripts and dependencies from showcase/package.json, adds site/** to the repo formatter, writes site/README.md and site/AGENTS.md, and updates every doc that still pointed at the old showcase/docs layout. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LdnJCJHVx2mfpfoHi6pbqG
oxfmt couldn't converge on two inline-code spans that escaped backticks inside a single-backtick span (`import(\`...\`)`), which made it mangle surrounding prose on reformat. Rewrote them as double-backtick spans, and moved the spec's Date/Status onto separate bullet lines so they survive reflow, then ran oxfmt so both files are clean under mage fmt:check. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LdnJCJHVx2mfpfoHi6pbqG
Each guide wrote its lede as a multi-line <p className="doc-lede"> block. MDX treats the lines inside a block-level JSX element as flow content and wraps them in their own paragraph, so the prerendered HTML was <p class="doc-lede"><p>...</p></p>. The browser's parser closes the outer <p> when the inner one opens, so the served DOM no longer matched the tree React hydrates against, and every docs page with a lede threw React error #418 in the production build. A <div> may hold a <p>, so the lede now parses exactly as rendered. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LdnJCJHVx2mfpfoHi6pbqG
Next 16's dev server refuses its dev resources to any origin but localhost. Opened at http://127.0.0.1:5179, the HMR websocket was refused (403, "Blocked cross-origin request to Next.js dev resource /_next/hmr") and the page never hydrated: the search input carried no React props, so its onFocus/onChange never ran, loadPagefind was never called, and neither the unavailable note nor a /_pagefind/pagefind.js request appeared. The same page at localhost hydrated and searched normally. Search itself was never at fault. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LdnJCJHVx2mfpfoHi6pbqG
MDX wraps a top-level lede paragraph in its own <p>; a <p> nested inside that <p> is invalid HTML, the browser re-parents it, and React throws hydration error #418 in production only. site/lib/lede.ts adds a pure checkLedeTags function (TDD: RED with the test importing a module that didn't exist yet, GREEN after implementing it), wired into scripts/check.ts so pnpm check fails the build if a guide regresses to <p className="doc-lede">. site/AGENTS.md's authoring recipe now states the rule and the reason. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LdnJCJHVx2mfpfoHi6pbqG
package.json pins packageManager to pnpm@12.3.4, matching the pnpm that wrote the lockfile; the lockfile gains the packageManagerDependencies block pnpm records for that pin. pnpm-workspace.yaml denies core-js's build script explicitly (its postinstall is only a donation banner) — pnpm treats an absent entry as pending approval and hard-fails `--frozen-lockfile` install, so `false` is what "don't grant it" has to be, not just removing the line. Verified with `pnpm install --frozen-lockfile` (exit 0). site/README.md's Deploying section lists the remaining one-time owner actions: NEXT_PUBLIC_POSTHOG_KEY scoped to Production only, PostHog's Cookieless server hash mode, keeping Vercel's System Environment Variables exposed (the gate reads NEXT_PUBLIC_VERCEL_ENV), enabling Corepack so the pinned pnpm is used, and confirming /_pagefind/pagefind.js returns 200 after the first preview deploy. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LdnJCJHVx2mfpfoHi6pbqG
…ration Prose and comments still described the retired Vite showcase docs app or its docs/public output path. Fix wording only, no behavior change: - "showcase docs'" -> "the site" in magefiles/magefile.go (Docs namespace doc), pkg/gen/clidocs/clidocs.go, pkg/gen/crddocs/crddocs.go, cmd/oap/clidocs_gen_test.go. - site/lib/manifest.ts: the manifest path is site/content/_manifest.json, hand-maintained, not "docs/_manifest.json ... the media pipeline writes." - showcase/.gitignore and showcase/engine/capture/clip.mjs: published media lives under site/public, copied there by hand, not docs/public. - site/app/(landing)/landing.css: the token-copy rationale is that site/ is its own package outside the web/ workspace, not that showcase/ is. - site/app/docs/docs.css: the theme attribute is stamped by next-themes before paint, not a hand-rolled "pre-paint script". - site/README.md / site/AGENTS.md gotcha: dev has no search index at all on a clean checkout; after any pnpm build, dev serves that (possibly stale) index like any other static file, rather than never having search. (site/AGENTS.md's half of this landed in the lede-rule commit, since git add swept the whole file.) Also moves docs/assets/brand/README.md's site/app/(landing)/OapMark.tsx entry from the "reference the files here directly" prose into the "Copies of the geometry" table it belongs in — OapMark inlines the logomark's geometry rather than loading the SVG file. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LdnJCJHVx2mfpfoHi6pbqG
Search lives in the docs layout, which persists across route changes.
Picking a result routed to a new page without clearing the query input
or result list, so the persistent layout kept showing them over content
the visitor didn't search for. A usePathname effect now clears the
input (via a ref, since it's uncontrolled) and resets state to idle on
every pathname change, bumping the generation counter first so a search
already in flight can't repopulate state after the clear.
Screenshot and ScreenshotSeries images are role="button" with
tabIndex={0} (a real <button> can't hold an <img> the way the lightbox
layouts need) but had no keyboard handler, so they were focusable but
not operable from a keyboard. A shared activateOnKey helper responds to
Enter and Space the way a native button would, calling preventDefault
on Space so the page doesn't scroll.
No new test infra: this repo's vitest setup only covers plain-function
node-environment tests (vitest.config.ts: environment "node", include
**/*.ts, no @testing-library/react or jsdom) and has no existing
component-test pattern to extend; verified instead via typecheck, the
full site test suite, and a production build.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LdnJCJHVx2mfpfoHi6pbqG
test:unit's stale-web-bundle check defaulted to master, which this repo doesn't have, so it logged a diff failure and skipped on every run. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LdnJCJHVx2mfpfoHi6pbqG
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LdnJCJHVx2mfpfoHi6pbqG
Picks up the oap directory and oap preferences families, the OAP_DESKTOP_SSH_KEY rename, and the new oap tools gen behavior. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LdnJCJHVx2mfpfoHi6pbqG
The repo's base branch is main. Update the audit generator's default diff base (and AUDIT_DIFF_BASE docs), the ship-gate and audit prose in AGENTS.md, the OWASP coverage page's assessment scope, and branch mentions in comments. Upstream skill refs pinned to a third-party repo's master branch and "master Secret" (a credential term) are unchanged. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LdnJCJHVx2mfpfoHi6pbqG
Each platform binds only its own modifier: on macOS Ctrl+K is the text-field kill-to-end-of-line binding, and Super+K belongs to the OS elsewhere. The search box shows the platform's hint once mounted (so server HTML never mismatches), declares aria-keyshortcuts, and Escape clears and blurs it. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LdnJCJHVx2mfpfoHi6pbqG
Lead with "a secure way to run enterprise AI agents" and follow the README's order: the credential-scope problem and its comparison table, the six primitives, the twenty-seven controls in six areas, Agent Builder, a compact "everything else" strip, then the OWASP map with the test evidence folded into it. Close on defense in depth. The hero terminal now offers the README's two local paths (Desktop and kind) instead of an install into an existing cluster. Drop the whitepapers section and its placeholder links, the seam grid, and the drifting internal counts. The "no telemetry" claim is narrowed to the runtime, since the site itself now carries cookieless analytics. The footer credits AuthZed, using SpiceDB. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LdnJCJHVx2mfpfoHi6pbqG
Cut every section's prose to short sentences and raise body text size and spacing, so the page scans rather than reads as a wall. Remove the hero and primitive-card chips, which repeated the text beside them; the OWASP coverage pills and the Draft marker stay because they carry status. Retitle the OWASP section "Coverage of the OWASP Agentic Top 10" and state the self-assessment plainly. The theme toggle moves from the nav to the footer, which also lets the wordmark stay visible in the nav at phone width. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LdnJCJHVx2mfpfoHi6pbqG
Split the landing footer into two rows: the mark and links on top, and a bottom bar with "Built by AuthZed, using SpiceDB" on the left and the theme toggle on the right. Raise the landing page's sans-serif text one pixel throughout; the monospace labels keep their 12px ceiling. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LdnJCJHVx2mfpfoHi6pbqG
The oversized "01"–"06" behind each section numbered chapters that no longer form a sequence, and competed with the numbering that does carry meaning (the four hero questions, the six primitives). Each section is still marked by its kicker and the rule above it. The section clipping that existed only to contain the numerals goes with them. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LdnJCJHVx2mfpfoHi6pbqG
Chromium can report navigator.userAgentData.platform as "" (some privacy configurations, and after device emulation). The `??` fallback kept the empty string, so a Mac was treated as non-Apple: the hint read "Ctrl K" and Cmd+K did nothing. platformName now lets an empty hint fall through, with table tests for each case. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LdnJCJHVx2mfpfoHi6pbqG
- SiteFooter (components/) replaces the landing-only footer and now sits under every docs guide too: links on top, the AuthZed credit bottom left, the theme toggle bottom right. It styles itself from --sf-* variables that .lp and .doc-app map, the same pattern as the toggle. The docs sidebar no longer carries a toggle. - The nav shows the logomark alone; the hero shows the full wordmark, sized by width (400px, capped at the column). The wordmark's per-theme ink swap moves out of docs.css into components/wordmark.css so the landing page gets it too. - Plainer claims: "The AI never decides what it's allowed to do. OAP checks every action before it runs." Building from source is framed as every image coming from code you can review. - Larger small text: monospace eyebrows, labels, captions and notes move up half a pixel to a pixel. Card eyebrows had been rendering at body size because `.lp-prim p` and `.lp-slab p` outranked them. - On phones, the OWASP table now hides the Known gap header along with its column, and its caption wraps instead of clipping. - OapMark moves to components/ (brand README updated). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LdnJCJHVx2mfpfoHi6pbqG
The area titles (18px/500) read almost the same as each bullet's bold lead-in (15.5px/500). They are now 22px with tighter tracking and a rule beneath, so each card reads heading first, then list. Card padding grows to match on desktop and tightens on phones. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LdnJCJHVx2mfpfoHi6pbqG
From an LLM-writing check of the rendered page: drop the "almost always" hedge from the problem heading, and rewrite four of the page's eight "X, not Y" reversals (the credential valet-key line, "not just what its task needs", "never the secret itself", "denied, never guessed"). The reversals that carry the point stay, as does the security intro. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LdnJCJHVx2mfpfoHi6pbqG
"Desktop · macOS" and "Kubernetes · kind" read as four options split by dots. The tabs are now "macOS desktop" and "Local Kubernetes", the README's own names, set in their natural case so "macOS" survives. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LdnJCJHVx2mfpfoHi6pbqG
- Under the four trust questions, one line now closes the loop: "OAP answers each one in the platform, before the agent acts. See how →", linking to the comparison table (#compare), which answers them row by row. - The problem heading states the consequence rather than a mismatch: "Your agent can reach everything its credentials can." Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LdnJCJHVx2mfpfoHi6pbqG
- The hero's single button is now "How it stays secure" (primary); the "Get started" button there is gone, since the nav already carries it. The line under the four questions stays, without its link. - The hero wordmark competed with the headline, so it goes; the nav logomark grows from 20px to 28px to carry the brand. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LdnJCJHVx2mfpfoHi6pbqG
The nav now shows the wordmark (logomark plus "Open Agent Primitives") at 38px tall in place of the bare logomark, so the one logo on the page names the project. The brand set has only the stacked two-line wordmark; a single-line lockup would be a new asset. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LdnJCJHVx2mfpfoHi6pbqG
"Six concerns every agent has to solve." broke as "…has to / solve." Section headings, the hero title and card titles now use text-wrap: balance, so lines come out even. Two phrases balancing would split badly are held together: "Twenty-seven controls," and the OWASP heading's "Top 10." with its Draft marker. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LdnJCJHVx2mfpfoHi6pbqG
The anatomy-of-a-check panel and its recorded-trace companion came after the comparison table had already made the point, gave no scenario for the denial, and showed a trace unrelated to the example. The section now ends on the table. Their styles go with them. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LdnJCJHVx2mfpfoHi6pbqG
"Every agent is built from them" read as if each agent must use all six. The primitives lede now says any agent can be built from them, using only the ones it needs. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LdnJCJHVx2mfpfoHi6pbqG
The primitives lede now runs definition first, then offering: "A primitive is a basic building block that agents rely on, whatever they do. OAP ships a working implementation of every one." Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LdnJCJHVx2mfpfoHi6pbqG
"The platform enforces every control. No prompt or tool output can affect enforcement." replaces the passive "enforced by the platform, not requested of the model" phrasing. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LdnJCJHVx2mfpfoHi6pbqG
The "Everything else" channels card named five surfaces. It now adds scheduled runs (bento) and sub-agent conversations (the agent kind), and says transports are pluggable. "Sub-agent conversations" rather than "agent-to-agent" keeps it consistent with the OWASP ASI07 row. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LdnJCJHVx2mfpfoHi6pbqG
Both used a placeholder; they now link to https://github.com/authzed/openagentprimitives. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LdnJCJHVx2mfpfoHi6pbqG
- The footer's Community link (landing and every docs page) now goes to the AuthZed Discord, https://discord.gg/TUd4k5McMX, where authzed.com/discord redirects. - The OWASP section's "Full assessment" button is gone; "Read the coverage map" remains. No example.invalid URLs are left in the site. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LdnJCJHVx2mfpfoHi6pbqG
- "Nothing phones home" was untrue (SpiceDB's default telemetry is left on), so that card becomes "Under your control": OAP runs inside a cluster your team operates. - The Channels card drops "sub-agent conversations"; the landing page is about channels, and the phrase contradicted the ASI07 row. - The ASI01 gap no longer mentions meta tools, which read as actions skipping authorization. - The footer says OAP is open source under Apache 2.0, linking LICENSE. - The OWASP credit now names the work, its author and its license with links, on the landing page and at the foot of the OWASP docs page. - The quickstart installs from examples/pm-agent, the path that exists. - README: Desktop is for trying OAP and demos, not production; the docs link to openap.org/docs, with local instructions kept. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- metadataBase is https://openap.org (lib/site.ts), so canonical and Open Graph URLs resolve to the production site on every deploy. - Every page has a canonical link, og:url, and the same current description; docs pages get article-type Open Graph tags. - A build-time 1200x630 share card (app/opengraph-image.tsx), attached explicitly to pages that set their own openGraph, since that replaces the inherited image. - robots.txt and sitemap.xml (the landing page plus all 131 guides). - favicon.ico and a 180px apple-touch-icon, drawn from the brand icon on a dark tile; the SVG favicons stay for browsers that use them. - A styled 404 page with links back to the docs and home, and one title. - /docs now redirects with 308 rather than 307. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Each change was confirmed against the code and approved item by item: - Drop the hero note that every image comes from reviewable code; the install also pulls third-party images. - "Built in and swappable" names the README's list (runner, authorization, approvals, sandboxing, credentials, memory, audit) rather than "every core component". - "Instant revocation" becomes "the next action is refused". - "Twenty-seven controls, in six areas" becomes "Controls in six areas", since the cards show a selection. - The comparison row's OAP answer to an injected instruction is "Cannot widen what it's authorized to do", which holds by default; plan gating is opt-in. README's table matches. - "Nothing is enabled until someone adds it" is scoped to tools and capabilities, since breakers and network policy are on by default. - The OWASP heading loses its Draft badge. - ASI05 describes per-session isolation instead of "deferred" work, and ASI07 is re-rated Partial: delegation is typed, authorized and bounded, and stays within one cluster. - The OWASP caption is counted from the rows (coverageSummary, tested), so a re-rating can't leave it stale. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Approved item by item, each checked against the code: - Rate limits and data-volume budgets are opt-in; only circuit breakers are on by default (safe-tools, OWASP ASI02). - The prompt-injection classifier ships; the OWASP page and the coverage HTML no longer say it doesn't. - Prompt delimiters are described as an aid to the model, not the boundary; the boundary is that tool output cannot reach a privileged action without the platform's checks (agent-loop, agent-definition, OWASP ASI01). - `oap install` examples pass --builder-starters, with a note that it or --without-builder is required. - Only GKE provisions artifact storage; EKS and AKS take --artifact-store-url. - The docs entry page leads with the primary message and defines a primitive. - One rule for who checks run against: the user an agent acts for, or a userless session's own principal (the session or a declared service) with no standing grants. - Sandboxes get micro-VM isolation when their class sets a runtime class, not by default. - install-desktop carries the build commands; ASI05/ASI06 gaps are stated plainly; the OWASP primitive names and Authorization link are fixed. - ASI07 is re-rated Partial on the docs page, in channels, and in the coverage HTML. - `oap channel` help no longer calls webhooks and schedules "future"; the CLI reference is regenerated. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Under 900px the sidebar used to be hidden entirely, taking the guide list, search and home link with it. It now becomes a sticky top bar with the wordmark, the search field and a Menu button; Menu opens the guide list as an overlay beneath the bar. The menu closes on navigation and on Escape (returning focus to the button), and search results drop down across the full width. DocNav holds only the open state, so the page still has a single search box. Desktop is unchanged. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- Links inside running text are underlined: docs articles, the footer credit and landing notes. Their colour alone was only ~2.4-2.8:1 against the text around them, under the 3:1 a colour-only link needs (WCAG 1.4.1). Text contrast itself already passed AA in both themes. - The image lightbox behaves as the modal it declares: focus moves to its close button, Tab can't leave it, focus returns to the thumbnail on close, and it is named by its caption. - The landing page's content sits in a <main> landmark. - The landing phone nav keeps "Docs" beside "Get started", with the wordmark and spacing trimmed so both fit inside the side padding. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- A failed index load is logged instead of swallowed, and on a deployed site the message reads "Search is unavailable right now." rather than the dev-only `pnpm build` hint. - A query that throws is caught, logged with the query, and shown as "Search failed. Try again." instead of an unhandled rejection. - A visually hidden status line announces the result count, "No matches.", or the failure to screen readers. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
HSTS, nosniff, X-Frame-Options DENY, a strict Referrer-Policy and a Permissions-Policy that denies camera, microphone and geolocation. In production a Content-Security-Policy limits everything to the site's own origin, plus i.authzed.com for analytics. Scripts need 'unsafe-inline' because the site is static, so there are no per-request nonces, and Pagefind needs 'wasm-unsafe-eval'. frame-ancestors is 'none'. Verified with no violations across the landing page, docs, search, the lightbox and video. It is left off in dev, which relies on eval. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The install overview lists Git, Go 1.26+, Mage, Docker with buildx and a Kubernetes cluster (e.g. kind), each linked to its official install page, then shows the clone and `mage build:oap` step. Desktop lists its extra requirements (Apple Silicon, Xcode Command Line Tools, Docker/buildx, curl, zstd), taken from magefiles/desktop.go, and install-init points to the common list. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The migration's design spec and implementation plan were working notes for building this branch, not project documentation. They are removed from the repository (kept locally) and docs/superpowers/ is ignored. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation
The docs site and the new landing page were two Vite entries under
showcase/docs/app, with docs on hash routes (/docs/#/<slug>), no shared layout, and no hosting. This moves both into one Next.js app in a top-levelsite/, deployed on Vercel at openap.org. Docs get real paths, and the two pages share one root layout, which carries the theme and the cookieless analytics.The landing page is also rewritten to tell the README's story, and the site is readied for a public launch.
Summary of changes
Site migration (
site/)@next/mdx. The 131 guides live at/docs/<slug>, prerendered, and an unknown slug returns 404.next-themesfor light and dark, and PostHog set to cookieless, pageviews only, production only, viai.authzed.com.next build, with Cmd+K (Ctrl+K off Apple platforms).check.tsvalidates the media manifest, the refs sidecars, every/docslink and anchor, and lede markup.showcase/docsand its Vite config are removed.Go and repo changes that go with it
clidocsandcrddocsemit/docs/oap-*and/docs/crd-*links.mage docs:cliwrites intosite/content/docs. The CLI reference is regenerated.main, notmaster. Othermasterreferences are updated too.oap channel's help text no longer calls webhooks and schedules "future".Landing page
Docs content
Reconciled with the code and the primary message:
oap installexamples pass--builder-starters;Install prerequisites are listed, each linking to the tool's own install page. README's Desktop line now says it's for trying OAP and demos.
Launch readiness
robots.txt, a sitemap, a favicon, an apple-touch-icon, and a styled 404 page.<main>landmark.Alternatives considered
metaexports or fighting a theme. Plain Next.js with@next/mdxreads the metadata natively.next-mdx-remote, asauthzed/webuses: it is archived and can't read ESM exports.Provenance
Ship gate
Results:
The branch is 2 commits behind
main(#5, #8). Neither touches a file this branch changes, so the suites ran on the branch as-is.Regeneration
+kubebuilder:rbacmarker or a CRD-shaping field inpkg/apis/v1alpha1/*_types.go→ ranmage gen:apiandmage manifests(not applicable)config/**→ ranmage manifests(not applicable)mage docs:cli/mage docs:crdmage fmt:alluntilmage fmt:checkis cleanCoverage
mage test:integration+mage test:e2eare green, or it touches none of those. It touches none of them.Before requesting review
The parts are coupled: the generators' new link format only resolves on the new site, the landing and docs share one layout and footer, and the launch fixes edit files the migration creates.
Reading the diff: most of the line count is the 131 guides moving from
showcase/docs/guidestosite/content/docs(history-preserving renames), their#/links rewritten to/docs/, and the regeneratedoap-*andcrd-*reference pages. The hand-written code issite/app,site/components,site/lib,site/scripts,site/next.config.mjs, plus the Go files underpkg/gen,magefilesandcmd/oap/internal/channelcmd. The docs prose edits from the launch review are in commitsaf268a8and3b4e74f.Before deploying (outside this repo)
site, with "Include files outside the root directory" on (the brand SVGs come fromdocs/assets/brand). Confirm the install step can runpnpm@12.3.4.NEXT_PUBLIC_POSTHOG_KEYfor Production. Enable cookieless server hash mode in PostHog.noindex.🤖 Generated with Claude Code