ops-loop-log.html 8.89 KB
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="utf-8" /><meta name="viewport" content="width=device-width,initial-scale=1" />
<title>Ops · Loop Log · LemonBoss PRD</title>
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link href="https://fonts.googleapis.com/css2?family=Fraunces:opsz,wght@9..144,300;9..144,500;9..144,700&family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;700&display=swap" rel="stylesheet" />
<link rel="stylesheet" href="assets/shell.css" />
</head>
<body data-page="ops-loop-log.html">
<div class="shell">
  <aside id="sidebar"></aside>
  <main class="page">
    <header class="page-head">
      <div class="crumb"><span class="pill">07 · OPS</span><span class="sep">/</span><span>Loop Log</span></div>
      <h1>Loop Log · L1 / L2 / L3 分组时间线</h1>
      <p class="deck">把 <code>timeline.ndjson</code> 按 L1 / L2 / L3 三轨道分组渲染。无新数据文件,纯视图。是问「当前出在哪个 loop」时人类的第一个跳转。</p>
    </header>
    <article class="body">

      <section>
        <h2>UI Wireframe</h2>
        <div class="mock">
          <div class="topbar">
            <span class="dot" style="background:#FF5F57"></span>
            <span class="dot" style="background:#FEBC2E"></span>
            <span class="dot" style="background:#28C840"></span>
            <span class="url">/devloop/p-731042/ops/loops</span>
          </div>
          <svg viewBox="0 0 1100 480" width="100%" role="img" aria-label="Loop Log wireframe">
            <rect width="1100" height="480" fill="#FAF7F1"/>
            <rect x="0" y="0" width="1100" height="48" fill="#0E0E10"/>
            <text x="20" y="32" font-family="Fraunces" font-size="16" fill="#FAF7F1">Loop Log · p-731042 · 最近 24h</text>

            <!-- Three swim lanes -->
            <g font-family="JetBrains Mono" font-size="11">
              <text x="20" y="84" fill="#6E48C3" font-weight="700">L3 · HUMAN</text>
              <line x1="120" y1="78" x2="1080" y2="78" stroke="#dcd5c4"/>
              <line x1="120" y1="78" x2="1080" y2="78" stroke="#ECE4FB" stroke-width="40"/>
              <line x1="120" y1="78" x2="1080" y2="78" stroke="#dcd5c4"/>

              <text x="20" y="158" fill="#C77C2C" font-weight="700">L2 · INTEGRATION</text>
              <line x1="120" y1="152" x2="1080" y2="152" stroke="#F7E8D2" stroke-width="40"/>

              <text x="20" y="240" fill="#0E8C5A" font-weight="700">L1 · UNIT</text>
              <line x1="120" y1="234" x2="1080" y2="234" stroke="#E2F2EA" stroke-width="40"/>
            </g>

            <!-- L3 events (lower frequency) -->
            <circle cx="180" cy="78" r="7" fill="#6E48C3"/>
            <text x="180" y="100" font-family="JetBrains Mono" font-size="9" text-anchor="middle" fill="#3B3B40">project_created</text>
            <circle cx="780" cy="78" r="7" fill="#6E48C3"/>
            <text x="780" y="60" font-family="JetBrains Mono" font-size="9" text-anchor="middle" fill="#3B3B40">+ OAuth feedback</text>

            <!-- L2 events (medium) -->
            <circle cx="320" cy="152" r="7" fill="#C77C2C"/>
            <text x="320" y="174" font-family="JetBrains Mono" font-size="9" text-anchor="middle" fill="#3B3B40">L2 run 1 · fail</text>
            <circle cx="500" cy="152" r="7" fill="#C77C2C"/>
            <text x="500" y="174" font-family="JetBrains Mono" font-size="9" text-anchor="middle" fill="#3B3B40">L2 run 2 · pass</text>
            <circle cx="920" cy="152" r="7" fill="#C7341A"/>
            <text x="920" y="174" font-family="JetBrains Mono" font-size="9" text-anchor="middle" fill="#C7341A">L2 run 3 · fail</text>

            <!-- L1 events (high frequency, dots only) -->
            <g fill="#0E8C5A">
              <circle cx="220" cy="234" r="4"/><circle cx="240" cy="234" r="4"/>
              <circle cx="260" cy="234" r="4"/><circle cx="280" cy="234" r="4"/>
              <circle cx="300" cy="234" r="4"/>
            </g>
            <g fill="#C7341A">
              <circle cx="232" cy="234" r="4"/>
            </g>
            <g fill="#0E8C5A">
              <circle cx="380" cy="234" r="4"/><circle cx="400" cy="234" r="4"/>
              <circle cx="420" cy="234" r="4"/>
            </g>
            <text x="260" y="256" font-family="JetBrains Mono" font-size="9" text-anchor="middle" fill="#0E8C5A">batch 1: 5 unit passed (1 retry)</text>

            <g fill="#0E8C5A">
              <circle cx="820" cy="234" r="4"/><circle cx="840" cy="234" r="4"/>
              <circle cx="860" cy="234" r="4"/>
            </g>
            <g fill="#C7341A">
              <circle cx="850" cy="234" r="4"/>
            </g>
            <text x="850" y="256" font-family="JetBrains Mono" font-size="9" text-anchor="middle" fill="#3B3B40">batch 2: 3 unit (oauth-*)</text>

            <!-- Time axis -->
            <line x1="120" y1="320" x2="1080" y2="320" stroke="#0E0E10"/>
            <text x="120" y="340" font-family="JetBrains Mono" font-size="10">10:00</text>
            <text x="320" y="340" font-family="JetBrains Mono" font-size="10">10:30</text>
            <text x="520" y="340" font-family="JetBrains Mono" font-size="10">11:00</text>
            <text x="720" y="340" font-family="JetBrains Mono" font-size="10">11:30</text>
            <text x="920" y="340" font-family="JetBrains Mono" font-size="10">12:00</text>

            <!-- Event detail (selected) -->
            <rect x="20" y="360" width="1060" height="100" rx="6" fill="#fff" stroke="#0E0E10"/>
            <text x="36" y="382" font-family="JetBrains Mono" font-size="11" fill="#0E0E10" font-weight="700">SELECTED · L2 run 3 · 12:04:21</text>
            <text x="36" y="404" font-family="JetBrains Mono" font-size="10" fill="#C7341A">FAIL · oauth callback returns 500 in step 2</text>
            <text x="36" y="422" font-family="JetBrains Mono" font-size="10" fill="#3B3B40">involves: oauth-be, oauth-fe, auth-mw</text>
            <text x="36" y="440" font-family="JetBrains Mono" font-size="10" fill="#3B3B40">→ BugTriager category: impl_bug · confidence 0.91 · 1 bug opened</text>
          </svg>
        </div>
      </section>

      <section>
        <h2>分组规则</h2>
        <p>本视图从 <code>timeline.ndjson</code> 读取所有事件,按 <code>kind</code> 字段分桶:</p>
        <table class="dense">
          <thead><tr><th>分到</th><th>kind 包含</th></tr></thead>
          <tbody>
            <tr><td><span class="tag L3">L3</span></td><td>project_created · prd_drafted · sdd_generated · human_feedback · sign_off · abandon</td></tr>
            <tr><td><span class="tag L2">L2</span></td><td>integration_started · integration_done · integration_failed · triage_*</td></tr>
            <tr><td><span class="tag L1">L1</span></td><td>unit_state · agent_started (Coder/Tester) · agent_done · unit_passed · unit_failed</td></tr>
            <tr><td>无</td><td>agent_started (PM/Architect/Integrator/Triager) → 归到对应 loop</td></tr>
          </tbody>
        </table>
      </section>

      <section>
        <h2>交互</h2>
        <ul>
          <li>顶部时间窗口选择:最近 1h / 24h / 全部 / 自定义</li>
          <li>点击任一事件 → 底部详情面板展开(如 wireframe)</li>
          <li>事件类型 chip 过滤(暂时隐藏某些 kind)</li>
          <li>缩放 / 平移时间轴(d3-zoom)</li>
          <li>「↗ Buglist」联动:选中 L2 事件 → 自动 filter buglist 到该 run 的 bug</li>
          <li>「↗ Changelog」联动:选中 PRD/SDD 事件 → 跳 changelog 对应条</li>
        </ul>
      </section>

      <section>
        <h2>L1 高频降采样</h2>
        <p>L1 事件可能一分钟几十条。视图层做<b>降采样</b>:</p>
        <ul>
          <li>同 unit 同 attempt 内多条 agent.step → 折叠为一个圆点</li>
          <li>同 wave 内连续 passed → 横线表示批次</li>
          <li>retry 失败用红色圆点,覆盖在绿色之上</li>
          <li>点击折叠批次 → 展开详细</li>
        </ul>
      </section>

      <section>
        <h2>L2 / L3 强调</h2>
        <p>L2 是 amber pulse 动画(如果 currently running),失败用 red 高亮。L3 事件用 violet 大圆点+ 上方文字标签,便于看「为什么改」。</p>
      </section>

      <section>
        <h2>关联视图</h2>
        <ul>
          <li><a href="ops-buglist.html">Buglist</a> · 看具体 bug</li>
          <li><a href="ops-changelog.html">Changelog</a> · 看 rev 变更</li>
          <li><a href="ops-progress.html">Progress</a> · 看实时进度</li>
          <li><a href="ui-dashboard.html">Dashboard</a> · 主看板</li>
        </ul>
      </section>

    </article>
    <nav class="prev-next"></nav>
    <footer class="site"><div><b>Section</b>07 · Ops</div><div><b>Page</b>ops-loop-log.html</div></footer>
  </main>
</div>
<script src="assets/shell.js"></script>
</body>
</html>