Files
6krrt/plans/docs-lift-a-pass.md
adlee-was-taken 69c969d104 plans: declare a valid Status on the six plans this branch adds
tests/test_plans_declare_status.py requires 'Status: <done|planned|in
progress|parked|reference> -- <reason>' in the first 8 lines.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N9biTbFC63yDfYfUsZmhgd
2026-09-26 21:46:15 -04:00

6.1 KiB

Docs pass after Lift A (PR #102)

Status: done -- executed on branch docs/lift-a-docs-pass Date: 2026-09-26 This brief is the contract. Keep the plan small: one todo per doc, each with exact section anchors. Do NOT read plans/no-progress-detection.md (reference only).

Goal

Bring the docs in line with what PR #102 shipped and what is running now. The docs describe the code as it is on this branch; where a doc and the code disagree, the code wins, and the todo says which line it checked.

Where the work happens

  • Worktree: /home/alee/Sources/6krrt-worktrees/docs-lift-a-pass, branch docs/lift-a-docs-pass, based on origin/main a24de1b plus three commits that already carry North Star #4 in CLAUDE.md, the incident #8 rewrite in docs/incidents.md, and the plans. Build on them; do not rewrite them.
  • Docs only. No code, config, test or unit-file changes.
  • Do not touch README.md, AGENTS.md, deploy/README.md: the owner has uncommitted edits to them in the main checkout. Anything that belongs in deploy/README.md goes in docs/watchdog.md instead, and the done report lists it for the owner to fold in.

What shipped (verify each against the code before writing it)

  • src/progress_detect.py: pure detector. Signals dup, top, slow, coverage; landed gating; read-only agents; canonical (sorted-key) args; bash command normalization (comment lines, cd dir &&, VAR=x prefixes dropped).
  • src/watchdog.py + deploy/llm-router-watchdog.{service,timer}: 5-minute oneshot. Judges only sessions with a tool call since the last tick, on their full history, per session; landed counts the session's own descendants only. Alert lifecycle in watchdog_alerts: trigger once, escalate once (LLM yes or 3 ticks), resolve once. Quiet no_opencode tick when opencode is closed. Optional local-model second opinion (does not veto).
  • src/notifier.py: desktop channel (notify-send), PagerDuty-Events-v2 shaped AlertEvent, per-channel min_severity, rate limit backed by the DB.
  • src/watchdog_store.py: tables watchdog_ticks, watchdog_verdicts, watchdog_alerts, watchdog_channel_settings.
  • Admin: Loops panel (index.html#loops), Watchdog card on Controls (last tick, verdicts, channels, Send test alert), per-model stall rollup and Block/Unblock on Models. New availability value blocked, excluded from routing and from pinned requests via _admin_excluded_models.
  • Endpoints: GET /admin/api/watchdog/status, POST /admin/api/watchdog/channels, POST /admin/api/watchdog/test-alert; availability endpoint accepts blocked.
  • Config: watchdog.* (incl. detector.*, dashboard_base_url), notifications.channels. Watchdog knobs are persisted-only (separate process).
  • deploy/opencode-plugin/router-link.js: the parentCache export made opencode 1.18 reject the whole plugin ("Plugin export is not a function" in ~/.local/share/opencode/log/opencode.log), so identity headers never reached the router from #99 until this fix. A loader-contract test now asserts every export is a function.
  • scripts/progress_backtest.py (--fixture replays the 15 labelled sessions; expect 8/15 flagged) and scripts/export_progress_fixture.py.
  • Operator state 2026-09-26: timer enabled ~15:18 EDT with unit paths repointed from %h/llm-router to %h/Sources/6krrt (production still runs from the dev checkout; see plans/deploy-separation.md); plugin fix installed and opencode restarted 15:19; router restarted 15:19:57.

Todos (one per doc)

  1. New docs/watchdog.md: what it catches and does not (steady spend is not waste), signals and thresholds, alert lifecycle, the admin surfaces, knobs, install (the sed repoint + enable --now), how to run --once, backtest, re-exporting the fixture, and known limits: sessions under 40 calls are invisible; the Atlas must-flag case sits exactly at cover_min 4.0; the stale localhost:4096 entry in rc-servers.json logs a harmless probe warning.
  2. CLAUDE.md: "What's built and working" (anchor ## What's built and working): add the modules above in the existing one-bullet style, linking docs/watchdog.md; update the tests/ bullet count from the real pytest --collect-only -q total. "Run as a service" (anchor ## Run as a service): one short paragraph on the watchdog timer. Do not edit the North Star section.
  3. docs/incidents.md #8: under Status, add that Lift A shipped (PR #102, a24de1b) and the timer is live; add the plugin-loader finding as Evidence (with the log line) and to the Human response timeline; add a symptom-table row "opencode plugin does nothing -> grep opencode.log for failed to load plugin". Keep the Evidence / labelled Theory convention in the file header.
  4. docs/admin-portal.md: sections for the Loops panel, the Watchdog card, and the Models rollup with Block/Unblock (where blocked differs from deprecated: an operator's reasoned stop, one click to undo).
  5. docs/api.md: the three watchdog endpoints and blocked on the availability endpoint (request/response shapes read from src/admin.py).
  6. docs/data-model.md: the four watchdog tables (from config/schema.sql), and blocked in the availability row at the models section (line ~34) and wherever admin_model_overrides is described.
  7. docs/clients.md (anchor ## Session-directory attribution (opencode plugin)) and docs/api.md near the X-Router-* table (line ~151): the plugin loader contract (every export must be a function) and how to confirm the plugin loaded.

Rules

  • ASCII only; no middle dots. Match each file's existing style and heading depth. Admin-portal docs describe the UI, they do not add prose to it.
  • Numbers and names come from the code on this branch, never from this brief.
  • Commit per todo, by explicit path. Never git add -A.
  • Do not push and do not open a PR. The done report lists commits and the items for deploy/README.md.
  • If a worker's context passes ~150k tokens, stop it and start a fresh one.

Write .omo/plans/docs-lift-a-pass.md, then stop and report.