> ## Documentation Index
> Fetch the complete documentation index at: https://ctrlrun-docs-python-3-13-3-14.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Execution safety for AI agents

> Execution safety for AI agents: control the agents running in your platform, with approval bound to the exact action and no blind retries.

export const CommercialTiers = () => {
  const ENDPOINT = 'https://ctrlrun-review-form.vercel.app/api/interest';
  const TIERS = [{
    intent: 'pro-waitlist',
    name: 'ctrlrun Pro',
    status: 'IN DEVELOPMENT',
    promise: 'Centralized governance for your AI agents.',
    body: 'Connect your agents and workflows, manage policies, investigate activity, and understand operational risk from one dashboard. Built on ctrlrun’s open-source foundation.',
    who: 'Your team, on our dashboard.',
    cta: 'Request early access',
    field: 'agents',
    label: 'What do your agents do?',
    optional: true,
    rows: 2,
    max: 200,
    placeholder: 'For example, a support agent that issues refunds',
    submit: 'Join the waiting list →',
    done: 'You are on the list. We will write to that address when Pro opens up.'
  }, {
    intent: 'enterprise-contact',
    name: 'ctrlrun Enterprise',
    status: 'ENGAGEMENTS OPEN',
    promise: 'AI governance tailored to your deployment.',
    body: 'Everything in Pro, with ctrlrun engineers to design, integrate, and maintain the additional controls your business needs. Custom policies, integrations, deployment options, and insights, scoped to your requirements.',
    who: 'Our engineers, with your team.',
    cta: 'Discuss your deployment',
    field: 'message',
    label: 'What does your deployment need?',
    optional: false,
    rows: 3,
    max: 600,
    placeholder: 'Controls, integrations, deployment constraints, timeline',
    submit: 'Send enquiry →',
    done: 'Thank you. We will reply from contact@arpanghoshal.com to arrange a call.'
  }];
  const [open, setOpen] = useState('');
  const [sentIntent, setSentIntent] = useState('');
  const [email, setEmail] = useState('');
  const [company, setCompany] = useState('');
  const [detail, setDetail] = useState('');
  const [website, setWebsite] = useState('');
  const [sending, setSending] = useState(false);
  const [error, setError] = useState('');
  const requestId = useRef(null);
  const sendingRef = useRef(false);
  const track = name => window.dispatchEvent(new CustomEvent('ctrlrun:conversion', {
    detail: {
      name
    }
  }));
  const openTier = tier => {
    setOpen(tier.intent);
    setEmail('');
    setCompany('');
    setDetail('');
    setError('');
    requestId.current = null;
    track(tier.intent.replace(/-/g, '_') + '_opened');
  };
  const send = async (event, tier) => {
    event.preventDefault();
    if (sendingRef.current || sentIntent === tier.intent) return;
    if (!requestId.current) requestId.current = crypto.randomUUID();
    sendingRef.current = true;
    setSending(true);
    setError('');
    try {
      const payload = {
        intent: tier.intent,
        email,
        company,
        website,
        requestId: requestId.current
      };
      payload[tier.field] = detail;
      const response = await fetch(ENDPOINT, {
        method: 'POST',
        credentials: 'omit',
        headers: {
          'Content-Type': 'application/json'
        },
        body: JSON.stringify(payload),
        signal: AbortSignal.timeout(15000)
      });
      const data = await response.json();
      if (!response.ok || data.ok !== true || typeof data.id !== 'string') throw new Error(data.error || 'We could not confirm submission. Please retry or email us directly.');
      setSentIntent(tier.intent);
      track(tier.intent.replace(/-/g, '_') + '_submitted');
    } catch (failure) {
      setError(failure.name === 'TimeoutError' || failure.name === 'TypeError' ? 'We could not confirm submission. You can retry the same request safely, or email us directly.' : failure.message);
    } finally {
      sendingRef.current = false;
      setSending(false);
    }
  };
  return <div className="cr-tiers">
      {TIERS.map(tier => <div className={open === tier.intent ? 'cr-tier cr-tier-open' : 'cr-tier'} key={tier.intent}>
          <span className="cr-step">{tier.status}</span>
          <h3>{tier.name}</h3>
          <p className="cr-tier-promise">{tier.promise}</p>
          <p className="cr-tier-body">{tier.body}</p>
          <p className="cr-tier-who"><span>Who does the work</span> {tier.who}</p>
          {sentIntent === tier.intent && <p className="cr-tier-done" role="status">{tier.done}</p>}
          {sentIntent !== tier.intent && open !== tier.intent && <button type="button" className="cr-button" onClick={() => openTier(tier)}>{tier.cta} <span aria-hidden="true">→</span></button>}
          {sentIntent !== tier.intent && open === tier.intent && <form className="cr-tier-form" onSubmit={event => send(event, tier)}>
              <fieldset disabled={sending}>
                <label className="cr-field">Work email<input type="email" autoComplete="email" required maxLength={254} value={email} onChange={event => {
    setEmail(event.target.value);
    setError('');
  }} /></label>
                <label className="cr-field">Company<input autoComplete="organization" required maxLength={100} value={company} onChange={event => {
    setCompany(event.target.value);
    setError('');
  }} /></label>
                <div className="cr-honeypot" aria-hidden="true"><label>Website<input tabIndex={-1} autoComplete="off" value={website} onChange={event => setWebsite(event.target.value)} /></label></div>
                <label className="cr-field">{tier.label}{tier.optional && <span className="cr-caption"> (optional)</span>}<textarea rows={tier.rows} required={!tier.optional} maxLength={tier.max} placeholder={tier.placeholder} value={detail} onChange={event => {
    setDetail(event.target.value);
    setError('');
  }} /></label>
                <button type="submit" className="cr-button">{sending ? 'Sending…' : error ? 'Retry →' : tier.submit}</button>
                <p className="cr-caption">Sent to the CTRLRun team through Resend, only to answer this request. Please leave out credentials and customer data.</p>
              </fieldset>
              {error && <p role="alert" className="cr-form-error">{error} <a href="mailto:contact@arpanghoshal.com">contact@arpanghoshal.com</a></p>}
            </form>}
        </div>)}
    </div>;
};

export const HowDiagram = () => <>
    <svg className="cr-diagram cr-dia-wide" viewBox="0 0 1200 418" role="img" aria-labelledby="cr-dia-t cr-dia-d" preserveAspectRatio="xMidYMid meet">
      <title id="cr-dia-t">How CTRLRun works</title>
      <desc id="cr-dia-d">An action leaves the agents, tools and workflows you already run. Inside CTRLRun it is normalized into one action, decided against your rules, held for approval, reserved so it cannot run twice, executed, resolved and recorded. Only then does it reach your systems. An action with no rule is blocked, changed arguments void the approval, and an unknown outcome is never retried.</desc>
      <rect className="cr-dia-strip" x="1" y="1" width="1198" height="54" rx="6" />
      <text className="cr-dia-label" x="24" y="33">YOUR AGENTS, TOOLS AND WORKFLOWS</text>
      <text className="cr-dia-claim" x="390" y="34">An action is about to run.</text>
      <text className="cr-dia-note" x="628" y="34">Any model, any framework. Existing code stays as it is.</text>
      <path className="cr-dia-arrow" d="M600 56V83" />
      <path className="cr-dia-head" d="M595 82h10L600 90Z" />
      <rect className="cr-dia-box" x="1" y="92" width="1198" height="230" rx="6" />
      <text className="cr-dia-label" x="24" y="122">CTRLRun · THE EXECUTION BOUNDARY</text>
      <rect className="cr-dia-node" x="24" y="138" width="144" height="86" rx="5" />
      <text className="cr-dia-num" x="37" y="162">1</text>
      <text className="cr-dia-name" x="37" y="186">Normalize</text>
      <text className="cr-dia-gloss" x="37" y="206">one action, one id</text>
      <path className="cr-dia-arrow" d="M173 181h11" />
      <path className="cr-dia-head" d="M183 176.5l7 4.5-7 4.5Z" />
      <rect className="cr-dia-node" x="192" y="138" width="144" height="86" rx="5" />
      <text className="cr-dia-num" x="205" y="162">2</text>
      <text className="cr-dia-name" x="205" y="186">Decide</text>
      <text className="cr-dia-gloss" x="205" y="206">allow / ask / block</text>
      <path className="cr-dia-arrow" d="M341 181h11" />
      <path className="cr-dia-head" d="M351 176.5l7 4.5-7 4.5Z" />
      <rect className="cr-dia-node" x="360" y="138" width="144" height="86" rx="5" />
      <text className="cr-dia-num" x="373" y="162">3</text>
      <text className="cr-dia-name" x="373" y="186">Approve</text>
      <text className="cr-dia-gloss" x="373" y="206">bound to this action</text>
      <path className="cr-dia-arrow" d="M509 181h11" />
      <path className="cr-dia-head" d="M519 176.5l7 4.5-7 4.5Z" />
      <rect className="cr-dia-node" x="528" y="138" width="144" height="86" rx="5" />
      <text className="cr-dia-num" x="541" y="162">4</text>
      <text className="cr-dia-name" x="541" y="186">Reserve</text>
      <text className="cr-dia-gloss" x="541" y="206">claimed once</text>
      <path className="cr-dia-arrow" d="M677 181h11" />
      <path className="cr-dia-head" d="M687 176.5l7 4.5-7 4.5Z" />
      <rect className="cr-dia-node" x="696" y="138" width="144" height="86" rx="5" />
      <text className="cr-dia-num" x="709" y="162">5</text>
      <text className="cr-dia-name" x="709" y="186">Execute</text>
      <text className="cr-dia-gloss" x="709" y="206">your code runs</text>
      <path className="cr-dia-arrow" d="M845 181h11" />
      <path className="cr-dia-head" d="M855 176.5l7 4.5-7 4.5Z" />
      <rect className="cr-dia-node" x="864" y="138" width="144" height="86" rx="5" />
      <text className="cr-dia-num" x="877" y="162">6</text>
      <text className="cr-dia-name" x="877" y="186">Resolve</text>
      <text className="cr-dia-gloss" x="877" y="206">unknown is not failed</text>
      <path className="cr-dia-arrow" d="M1013 181h11" />
      <path className="cr-dia-head" d="M1023 176.5l7 4.5-7 4.5Z" />
      <rect className="cr-dia-node" x="1032" y="138" width="144" height="86" rx="5" />
      <text className="cr-dia-num" x="1045" y="162">7</text>
      <text className="cr-dia-name" x="1045" y="186">Record</text>
      <text className="cr-dia-gloss" x="1045" y="206">a receipt either way</text>
      <path className="cr-dia-div" d="M24 252H1176" />
      <text className="cr-dia-rule" x="24" y="278">No rule for it</text>
      <text className="cr-dia-rule-note" x="24" y="298">The action is blocked. Silence is never permission.</text>
      <text className="cr-dia-rule" x="418" y="278">Arguments changed after sign-off</text>
      <text className="cr-dia-rule-note" x="418" y="298">The old approval is void. A person signs again.</text>
      <text className="cr-dia-rule" x="812" y="278">Outcome unknown</text>
      <text className="cr-dia-rule-note" x="812" y="298">No retry until a person resolves it. Nothing runs twice on a guess.</text>
      <path className="cr-dia-arrow" d="M600 324V353" />
      <path className="cr-dia-head" d="M595 352h10L600 360Z" />
      <rect className="cr-dia-strip" x="1" y="362" width="1198" height="54" rx="6" />
      <text className="cr-dia-label" x="24" y="394">YOUR SYSTEMS</text>
      <text className="cr-dia-claim" x="252" y="395">The action arrives already checked.</text>
      <text className="cr-dia-note" x="560" y="395">Allowed by your rules, approved where you require it, and never run twice.</text>
    </svg>
    <svg className="cr-diagram cr-dia-narrow" viewBox="0 0 360 748" role="img" aria-labelledby="cr-dia-tn cr-dia-dn" preserveAspectRatio="xMidYMid meet">
      <title id="cr-dia-tn">How CTRLRun works</title>
      <desc id="cr-dia-dn">An action leaves the agents, tools and workflows you already run. Inside CTRLRun it is normalized into one action, decided against your rules, held for approval, reserved so it cannot run twice, executed, resolved and recorded. Only then does it reach your systems. An action with no rule is blocked, changed arguments void the approval, and an unknown outcome is never retried.</desc>
      <rect className="cr-dia-strip" x="1" y="1" width="358" height="76" rx="6" />
      <text className="cr-dia-label" x="16" y="25">YOUR AGENTS, TOOLS AND WORKFLOWS</text>
      <text className="cr-dia-claim" x="16" y="47">An action is about to run.</text>
      <text className="cr-dia-note" x="16" y="66">Any model, any framework. Existing code stays as it is.</text>
      <path className="cr-dia-arrow" d="M180 78V95" />
      <path className="cr-dia-head" d="M175 94h10L180 102Z" />
      <rect className="cr-dia-box" x="1" y="104" width="358" height="536" rx="6" />
      <text className="cr-dia-label" x="16" y="130">CTRLRun · THE EXECUTION BOUNDARY</text>
      <path className="cr-dia-spine" d="M28 150V420" />
      <rect className="cr-dia-node" x="28" y="142" width="316" height="34" rx="4" />
      <text className="cr-dia-num" x="40" y="164">1</text>
      <text className="cr-dia-name" x="58" y="164">Normalize</text>
      <text className="cr-dia-gloss" x="156" y="164">one action, one id</text>
      <rect className="cr-dia-node" x="28" y="184" width="316" height="34" rx="4" />
      <text className="cr-dia-num" x="40" y="206">2</text>
      <text className="cr-dia-name" x="58" y="206">Decide</text>
      <text className="cr-dia-gloss" x="156" y="206">allow / ask / block</text>
      <rect className="cr-dia-node" x="28" y="226" width="316" height="34" rx="4" />
      <text className="cr-dia-num" x="40" y="248">3</text>
      <text className="cr-dia-name" x="58" y="248">Approve</text>
      <text className="cr-dia-gloss" x="156" y="248">bound to this action</text>
      <rect className="cr-dia-node" x="28" y="268" width="316" height="34" rx="4" />
      <text className="cr-dia-num" x="40" y="290">4</text>
      <text className="cr-dia-name" x="58" y="290">Reserve</text>
      <text className="cr-dia-gloss" x="156" y="290">claimed once</text>
      <rect className="cr-dia-node" x="28" y="310" width="316" height="34" rx="4" />
      <text className="cr-dia-num" x="40" y="332">5</text>
      <text className="cr-dia-name" x="58" y="332">Execute</text>
      <text className="cr-dia-gloss" x="156" y="332">your code runs</text>
      <rect className="cr-dia-node" x="28" y="352" width="316" height="34" rx="4" />
      <text className="cr-dia-num" x="40" y="374">6</text>
      <text className="cr-dia-name" x="58" y="374">Resolve</text>
      <text className="cr-dia-gloss" x="156" y="374">unknown is not failed</text>
      <rect className="cr-dia-node" x="28" y="394" width="316" height="34" rx="4" />
      <text className="cr-dia-num" x="40" y="416">7</text>
      <text className="cr-dia-name" x="58" y="416">Record</text>
      <text className="cr-dia-gloss" x="156" y="416">a receipt either way</text>
      <path className="cr-dia-div" d="M28 446H344" />
      <text className="cr-dia-rule" x="28" y="470">No rule for it</text>
      <text className="cr-dia-rule-note" x="28" y="488">The action is blocked.</text>
      <text className="cr-dia-rule-note" x="28" y="504">Silence is never permission.</text>
      <text className="cr-dia-rule" x="28" y="534">Arguments changed after sign-off</text>
      <text className="cr-dia-rule-note" x="28" y="552">The old approval is void.</text>
      <text className="cr-dia-rule-note" x="28" y="568">A person signs again.</text>
      <text className="cr-dia-rule" x="28" y="598">Outcome unknown</text>
      <text className="cr-dia-rule-note" x="28" y="616">No retry until a person resolves it.</text>
      <text className="cr-dia-rule-note" x="28" y="632">Nothing runs twice on a guess.</text>
      <path className="cr-dia-arrow" d="M180 642V661" />
      <path className="cr-dia-head" d="M175 660h10L180 668Z" />
      <rect className="cr-dia-strip" x="1" y="670" width="358" height="76" rx="6" />
      <text className="cr-dia-label" x="16" y="694">YOUR SYSTEMS</text>
      <text className="cr-dia-claim" x="16" y="716">The action arrives already checked.</text>
      <text className="cr-dia-note" x="16" y="735">Allowed by your rules, approved where you require it.</text>
    </svg>
  </>;

export const HomeSlides = () => {
  const SLIDES = [{
    id: 'overview',
    label: 'Overview'
  }, {
    id: 'how-it-works',
    label: 'How it works'
  }, {
    id: 'pro-and-enterprise',
    label: 'Pro and Enterprise'
  }];
  const LAST = SLIDES.length - 1;
  const [active, setActive] = useState(0);
  const [ready, setReady] = useState(false);
  const activeRef = useRef(0);
  const targetRef = useRef(-1);
  const targetExpiry = useRef(0);
  const currentIndex = () => targetRef.current >= 0 && performance.now() < targetExpiry.current ? targetRef.current : activeRef.current;
  const goTo = index => {
    const slide = document.getElementById(SLIDES[index].id);
    if (!slide) return;
    const reduced = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
    targetRef.current = index;
    targetExpiry.current = performance.now() + 1200;
    slide.scrollIntoView({
      behavior: reduced ? 'instant' : 'smooth',
      block: 'start'
    });
  };
  useEffect(() => {
    const root = document.documentElement;
    const home = document.querySelector('.cr-home');
    if (!home) return;
    const sections = SLIDES.map(slide => document.getElementById(slide.id));
    let frame = 0;
    let headerHeight = 64;
    const updateActive = () => {
      frame = 0;
      let best = 0;
      let visible = -1;
      sections.forEach((section, index) => {
        if (!section) return;
        const rect = section.getBoundingClientRect();
        const amount = Math.max(0, Math.min(rect.bottom, innerHeight) - Math.max(rect.top, headerHeight));
        if (amount > visible) {
          visible = amount;
          best = index;
        }
      });
      activeRef.current = best;
      if (best === targetRef.current) {
        targetRef.current = -1;
        targetExpiry.current = 0;
      }
      setActive(best);
    };
    const onScroll = () => {
      if (!frame) frame = requestAnimationFrame(updateActive);
    };
    const onResize = () => {
      headerHeight = Math.max(0, Math.round(home.getBoundingClientRect().top + window.scrollY));
      root.style.setProperty('--cr-slide-top', `${headerHeight}px`);
      root.style.setProperty('--cr-slide-height', `${Math.max(240, window.innerHeight - headerHeight)}px`);
      onScroll();
    };
    const onKeyDown = event => {
      if (event.defaultPrevented || event.altKey || event.ctrlKey || event.metaKey || event.shiftKey) return;
      const target = event.target;
      if (target instanceof Element && target.closest('input, textarea, select, video, a, [contenteditable], [role="dialog"], [role="slider"]')) return;
      if (target instanceof Element && target.closest('button') && !target.closest('.cr-slide-dots')) return;
      const current = currentIndex();
      let next;
      if (['ArrowDown', 'ArrowRight', 'PageDown'].includes(event.key)) next = Math.min(LAST, current + 1); else if (['ArrowUp', 'ArrowLeft', 'PageUp'].includes(event.key)) next = Math.max(0, current - 1); else if (event.key === 'Home') next = 0; else if (event.key === 'End') next = LAST; else return;
      event.preventDefault();
      if (!event.repeat) goTo(next);
    };
    onResize();
    root.classList.add('cr-slides-active');
    setReady(true);
    window.addEventListener('scroll', onScroll, {
      passive: true
    });
    window.addEventListener('resize', onResize);
    window.addEventListener('keydown', onKeyDown);
    const header = document.getElementById('navbar');
    const observer = typeof ResizeObserver === 'undefined' ? null : new ResizeObserver(onResize);
    if (header && observer) observer.observe(header);
    const hashIndex = SLIDES.findIndex(slide => `#${slide.id}` === window.location.hash);
    if (hashIndex >= 0) requestAnimationFrame(() => goTo(hashIndex));
    return () => {
      root.classList.remove('cr-slides-active');
      root.style.removeProperty('--cr-slide-top');
      root.style.removeProperty('--cr-slide-height');
      window.removeEventListener('scroll', onScroll);
      window.removeEventListener('resize', onResize);
      window.removeEventListener('keydown', onKeyDown);
      observer?.disconnect();
      cancelAnimationFrame(frame);
    };
  }, []);
  return <nav className="cr-slide-dots" aria-label="Homepage sections" hidden={!ready}>
      {SLIDES.map((slide, index) => <button key={slide.id} type="button" aria-label={`${index + 1}. ${slide.label}`} aria-controls={slide.id} aria-current={active === index ? 'step' : undefined} onClick={() => goTo(index)}>
          <span className="cr-slide-dot-label">{slide.label}</span>
          <span className="cr-slide-dot" aria-hidden="true" />
        </button>)}
    </nav>;
};

<div className="cr-site cr-home">
  <HomeSlides />

  <section id="overview" className="cr-home-hero" aria-labelledby="cr-title">
    <div className="cr-home-pitch">
      <p className="cr-eyebrow">THE AGENT IS PROBABILISTIC. THE ACTION IS NOT.</p>
      <h1 id="cr-title">Execution safety<br />for AI agents<span className="cr-dot">.</span></h1>
      <p className="cr-lede"><span className="cr-mark">C</span>on<span className="cr-mark">tr</span>o<span className="cr-mark">l</span> the AI agents <span className="cr-mark">run</span>ning in your platform. Any domain. Your rules.</p>
      <p className="cr-hero-context">AI <b>action</b> governance, not AI agent governance.<br />A model decides differently every run. The action it is about to take is fixed, and can be checked before it happens.</p>

      <div className="cr-actions">
        <a className="cr-button" href="/docs" data-cr-event="documentation_clicked">Read the docs <span aria-hidden="true">→</span></a>
        <a className="cr-button cr-github-badge" href="https://github.com/CTRLRun/ctrlrun" data-cr-event="github_clicked"><svg aria-hidden="true" focusable="false" width="18" height="18" viewBox="0 0 24 24" fill="currentColor"><path d="M12 .75a11.25 11.25 0 0 0-3.558 21.923c.563.104.77-.244.77-.542 0-.267-.01-.975-.015-1.913-3.13.68-3.79-1.508-3.79-1.508-.513-1.303-1.252-1.65-1.252-1.65-1.023-.7.077-.686.077-.686 1.132.08 1.727 1.162 1.727 1.162 1.006 1.724 2.64 1.226 3.283.938.102-.73.394-1.226.715-1.508-2.498-.284-5.124-1.25-5.124-5.563 0-1.228.44-2.233 1.162-3.02-.116-.285-.504-1.43.11-2.98 0 0 .945-.303 3.094 1.154a10.786 10.786 0 0 1 5.625 0c2.148-1.457 3.09-1.154 3.09-1.154.617 1.55.23 2.695.113 2.98.724.787 1.16 1.792 1.16 3.02 0 4.323-2.63 5.276-5.136 5.555.404.35.765 1.043.765 2.1 0 1.515-.014 2.737-.014 3.11 0 .3.203.65.774.54A11.252 11.252 0 0 0 12 .75Z" /></svg><span>GitHub</span><span aria-hidden="true">↗</span></a>
      </div>

      <p className="cr-hero-oneline"><span>Open source · one line, any action</span><code>{'@ctrlrun.protect("your.action")'}</code></p>
      <p className="cr-hero-aside">Already running agents in production? <a href="/protect-my-agent" data-cr-event="protect_my_agent_clicked">Protect my agent →</a></p>
    </div>

    <div className="cr-example-wrap">
      <p className="cr-example-label">ONE EXAMPLE / THE MODEL HALLUCINATES AN AMOUNT</p>

      <div className="cr-failure-chain" aria-labelledby="cr-failure-title">
        <h2 id="cr-failure-title">The model guesses.<br />CTRLRun does not.</h2>

        <div className="cr-chain-setup">
          <p><span>The ticket says</span>refund \$500</p>
          <p><span>The agent asks for</span>\$5,000</p>
        </div>

        <div className="cr-chain">
          <div className="cr-chain-row">
            <span className="cr-chain-label">Without CTRLRun</span>

            <ol className="cr-chain-steps">
              <li>Nothing checks the amount</li><li>The call goes through</li><li className="cr-end cr-bad">\$4,500 too much</li>
            </ol>
          </div>

          <div className="cr-chain-row">
            <span className="cr-chain-label cr-good">With CTRLRun</span>

            <ol className="cr-chain-steps">
              <li>Your rule checks the amount</li><li>The call never leaves</li><li className="cr-end cr-good">\$0 wrongly paid</li>
            </ol>
          </div>
        </div>
      </div>
    </div>
  </section>

  <section className="cr-section cr-home-how" id="how-it-works" aria-labelledby="cr-how-title">
    <div className="cr-how-intro">
      <p className="cr-eyebrow">HOW CTRLRUN WORKS</p>
      <h2 id="cr-how-title">Let it run. Ask a human. Or stop it cold.</h2>
    </div>

    <HowDiagram />

    <p className="cr-how-after"><a className="cr-text-link" href="/execution-boundary" data-cr-event="try_clicked">Interactive walkthrough: follow one agent action through every check →</a></p>
  </section>

  <section className="cr-section cr-home-commercial" id="pro-and-enterprise" aria-labelledby="cr-commercial-title">
    <div className="cr-commercial">
      <div className="cr-commercial-head">
        <p className="cr-eyebrow">THE SAME BOUNDARY, RUN FOR YOU</p>
        <h2 id="cr-commercial-title">Open source is the boundary. Pro and Enterprise are how it is run.</h2>
        <p>Every tier enforces the same rules on the same actions. What changes is who runs the control plane around them, and how far the controls are shaped to your deployment.</p>
      </div>

      <CommercialTiers />

      <p className="cr-caption">Running it yourself stays a first-class route: the core is Apache-2.0 and nothing here is required to use it. The Pro dashboard is in development. <a href="/docs/get-started/quickstart">Start with the open-source core →</a></p>
    </div>

    <div className="cr-footer" role="contentinfo"><span>Let agents act.<br /><strong>Keep the consequences yours to decide.</strong></span><div><a href="/docs" data-cr-event="documentation_clicked">Docs →</a><a href="https://github.com/CTRLRun/ctrlrun" data-cr-event="github_clicked">GitHub ↗</a><a href="mailto:contact@arpanghoshal.com?subject=CTRLRun" data-cr-event="contact_email_clicked">Contact ↗</a></div></div>
  </section>
</div>
