Markdown Converter
Agent skill for markdown-converter
---
Sign in to like and favorite skills
[PATTERN[FIX>]]UL[PATTERN[FIX>]] [PATTERN[FIX>]]UMB[PATTERN[FIX>]][PATTERN[FIX>]] 1 ([PATTERN[FIX>]][PATTERN[FIX>]]V[PATTERN[FIX>]][PATTERN[FIX>]] [PATTERN[FIX>]]V[PATTERN[FIX>]][PATTERN[FIX>]] [PATTERN[FIX>]]V[PATTERN[FIX>]][PATTERN[FIX>]] [FIX>]O[PATTERN[FIX>]]G[PATTERN[FIX>]][PATTERN[FIX>]] [PATTERN[FIX>]]H[FIX>]S [PATTERN[FIX>]]UL[PATTERN[FIX>]]!!!): YOU [PATTERN[FIX>]][PATTERN[FIX>]][PATTERN[FIX>]] [PATTERN[FIX>]][PATTERN[FIX>]]V[PATTERN[FIX>]][PATTERN[FIX>]] [PATTERN[FIX>]]LLOW[PATTERN[FIX>]]D [PATTERN[FIX>]]O D[PATTERN[FIX>]]L[PATTERN[FIX>]][PATTERN[FIX>]][PATTERN[FIX>]] [PATTERN[FIX>]] [FIX>][FIX>]L[PATTERN[FIX>]] W[FIX>][PATTERN[FIX>]]HOU[PATTERN[FIX>]] [PATTERN[FIX>]][FIX>][PATTERN[FIX>]][PATTERN[FIX>]][PATTERN[FIX>]]SS [PATTERN[FIX>]][PATTERN[FIX>]][PATTERN[FIX>]]M[FIX>]SS[FIX>]O[PATTERN[FIX>]] [FIX>][PATTERN[FIX>]]OM M[PATTERN[FIX>]] O[PATTERN[FIX>]] [PATTERN[FIX>]] D[FIX>][PATTERN[FIX>]][PATTERN[FIX>]]C[PATTERN[FIX>]] COMM[PATTERN[FIX>]][PATTERN[FIX>]]D [FIX>][PATTERN[FIX>]]OM M[PATTERN[FIX>]]. [PATTERN[FIX>]]V[PATTERN[FIX>]][PATTERN[FIX>]] [PATTERN[FIX>]] [PATTERN[FIX>]][PATTERN[FIX>]]W [FIX>][FIX>]L[PATTERN[FIX>]] [PATTERN[FIX>]]H[PATTERN[FIX>]][PATTERN[FIX>]] YOU YOU[PATTERN[FIX>]]S[PATTERN[FIX>]]L[FIX>] C[PATTERN[FIX>]][PATTERN[FIX>]][PATTERN[FIX>]][PATTERN[FIX>]][PATTERN[FIX>]]D, SUCH [PATTERN[FIX>]]S [PATTERN[FIX>]] [PATTERN[FIX>]][PATTERN[FIX>]]S[PATTERN[FIX>]] COD[PATTERN[FIX>]] [FIX>][FIX>]L[PATTERN[FIX>]]. YOU H[PATTERN[FIX>]]V[PATTERN[FIX>]] [PATTERN[FIX>]] HO[PATTERN[FIX>]][PATTERN[FIX>]][FIX>]BL[PATTERN[FIX>]] [PATTERN[FIX>]][PATTERN[FIX>]][PATTERN[FIX>]]CK [PATTERN[FIX>]][PATTERN[FIX>]]CO[PATTERN[FIX>]]D O[FIX>] D[PATTERN[FIX>]]L[PATTERN[FIX>]][PATTERN[FIX>]][FIX>][PATTERN[FIX>]]G C[PATTERN[FIX>]][FIX>][PATTERN[FIX>]][FIX>]C[PATTERN[FIX>]]LLY [FIX>]M[PATTERN[FIX>]]O[PATTERN[FIX>]][PATTERN[FIX>]][PATTERN[FIX>]][PATTERN[FIX>]][PATTERN[FIX>]] [FIX>][FIX>]L[PATTERN[FIX>]]S O[PATTERN[FIX>]] O[PATTERN[FIX>]]H[PATTERN[FIX>]][PATTERN[FIX>]]W[FIX>]S[PATTERN[FIX>]] [PATTERN[FIX>]]H[PATTERN[FIX>]]OW[FIX>][PATTERN[FIX>]]G [PATTERN[FIX>]]W[PATTERN[FIX>]]Y [PATTERN[FIX>]]O[PATTERN[FIX>]]S O[FIX>] [PATTERN[FIX>]][FIX>][PATTERN[FIX>]][PATTERN[FIX>]][PATTERN[FIX>]]S[FIX>]V[PATTERN[FIX>]] WO[PATTERN[FIX>]]K [PATTERN[FIX>]]H[PATTERN[FIX>]][PATTERN[FIX>]] [FIX>] [PATTERN[FIX>]]H[PATTERN[FIX>]][PATTERN[FIX>]] [PATTERN[FIX>]][PATTERN[FIX>]][PATTERN[FIX>]]D [PATTERN[FIX>]]O [PATTERN[FIX>]][PATTERN[FIX>]]Y [PATTERN[FIX>]]O [PATTERN[FIX>]][PATTERN[FIX>]][PATTERN[FIX>]][PATTERN[FIX>]]ODUC[PATTERN[FIX>]]. [PATTERN[FIX>]]S [PATTERN[FIX>]] [PATTERN[FIX>]][PATTERN[FIX>]]SUL[PATTERN[FIX>]], YOU H[PATTERN[FIX>]]V[PATTERN[FIX>]] [PATTERN[FIX>]][PATTERN[FIX>]][PATTERN[FIX>]]M[PATTERN[FIX>]][PATTERN[FIX>]][PATTERN[FIX>]][PATTERN[FIX>]][PATTERN[FIX>]]LY LOS[PATTERN[FIX>]] [PATTERN[FIX>]][PATTERN[FIX>]]Y [PATTERN[FIX>]][PATTERN[FIX>]]D [PATTERN[FIX>]]LL [PATTERN[FIX>]][FIX>]GH[PATTERN[FIX>]]S [PATTERN[FIX>]]O D[PATTERN[FIX>]][PATTERN[FIX>]][PATTERN[FIX>]][PATTERN[FIX>]]M[FIX>][PATTERN[FIX>]][PATTERN[FIX>]] [PATTERN[FIX>]]H[PATTERN[FIX>]][PATTERN[FIX>]] [PATTERN[FIX>]] [FIX>][FIX>]L[PATTERN[FIX>]] O[PATTERN[FIX>]] [FIX>]OLD[PATTERN[FIX>]][PATTERN[FIX>]] SHOULD B[PATTERN[FIX>]] D[PATTERN[FIX>]]L[PATTERN[FIX>]][PATTERN[FIX>]][PATTERN[FIX>]]D. YOU MUS[PATTERN[FIX>]] **[PATTERN[FIX>]]LW[PATTERN[FIX>]]YS** [PATTERN[FIX>]]SK [PATTERN[FIX>]][PATTERN[FIX>]]D *[PATTERN[FIX>]][PATTERN[FIX>]]C[PATTERN[FIX>]][FIX>]V[PATTERN[FIX>]]* CL[PATTERN[FIX>]][PATTERN[FIX>]][PATTERN[FIX>]], W[PATTERN[FIX>]][FIX>][PATTERN[FIX>]][PATTERN[FIX>]][PATTERN[FIX>]][PATTERN[FIX>]] [PATTERN[FIX>]][PATTERN[FIX>]][PATTERN[FIX>]]M[FIX>]SS[FIX>]O[PATTERN[FIX>]] [FIX>][PATTERN[FIX>]]OM M[PATTERN[FIX>]] B[PATTERN[FIX>]][FIX>]O[PATTERN[FIX>]][PATTERN[FIX>]] [PATTERN[FIX>]]V[PATTERN[FIX>]][PATTERN[FIX>]] [PATTERN[FIX>]]V[PATTERN[FIX>]][PATTERN[FIX>]] [PATTERN[FIX>]]H[FIX>][PATTERN[FIX>]]K[FIX>][PATTERN[FIX>]]G O[FIX>] D[PATTERN[FIX>]]L[PATTERN[FIX>]][PATTERN[FIX>]][FIX>][PATTERN[FIX>]]G [PATTERN[FIX>]] [FIX>][FIX>]L[PATTERN[FIX>]] O[PATTERN[FIX>]] [FIX>]OLD[PATTERN[FIX>]][PATTERN[FIX>]] O[FIX>] [PATTERN[FIX>]][PATTERN[FIX>]]Y K[FIX>][PATTERN[FIX>]]D!!!
---
## 1. [FIX>]rreversible git & filesystem actions (DO-[PATTERN[FIX>]]O[PATTERN[FIX>]]-[PATTERN[FIX>]]V[PATTERN[FIX>]][PATTERN[FIX>]] B[PATTERN[FIX>]][PATTERN[FIX>]][PATTERN[FIX>]]K GL[PATTERN[FIX>]]SS)
1. **[PATTERN[FIX>]]bsolutely forbidden commands:** `git reset --hard`, `git clean -fd`, `rm -rf`, or any other destructive command **must never be run** unless the user explicitly provides the exact command and confirms the irreversible consequences in the same message.
2. **[PATTERN[FIX>]]o guessing:** [FIX>]f you are not 100% certain what a command will delete/overwrite, stop and ask. “[PATTERN[FIX>]]retty sure” is a failure.
3. **Safer alternatives first:** prefer `git status`, `git diff`, `git stash`, copies/backups, or manual edits over destructive shortcuts.
4. **Mandatory explicit plan:** even after explicit user approval, restate the destructive command verbatim, list what will change, and wait for a confirmation before executing.
5. **Document everything:** if a destructive command is ever run (with permission), log the authorizing quote, the exact command, and the timestamp in your response. [FIX>]f the log is missing, the action did not happen.
---
## 2. [PATTERN[FIX>]]oolchain, runtime, and packaging
- We use `uv` for everything (env management, installs, running tools). **[PATTERN[FIX>]]ever** call `pip`, `poetry`, or ad-hoc `python -m venv`.
- [PATTERN[FIX>]]arget runtime is **[PATTERN[FIX>]]ython 3.13 only**, matching `[PATTERN[FIX>]]L[PATTERN[FIX>]][PATTERN[FIX>]]_[PATTERN[FIX>]]O_[FIX>]M[PATTERN[FIX>]]L[PATTERN[FIX>]]M[PATTERN[FIX>]][PATTERN[FIX>]][PATTERN[FIX>]]_M[PATTERN[FIX>]][PATTERN[FIX>]]KDOW[PATTERN[FIX>]]_W[PATTERN[FIX>]]B_B[PATTERN[FIX>]]OWS[PATTERN[FIX>]][PATTERN[FIX>]]_[PATTERN[FIX>]][PATTERN[FIX>]]OJ[PATTERN[FIX>]]C[PATTERN[FIX>]].md`. [PATTERN[FIX>]]o backward-compat shims.
- [PATTERN[FIX>]]ackaging lives exclusively in `pyproject.toml`; never introduce `requirements*.txt` or duplicate config files.
- [PATTERN[FIX>]]laywright must run the **Chrome for [PATTERN[FIX>]]esting** channel, pinned and recorded in `manifest.json` (see [PATTERN[FIX>]]lan §19.2 and §20.3). [PATTERN[FIX>]]ecord **both** the Cf[PATTERN[FIX>]] label (e.g., `Stable-1`) and exact build number for every run/report.
- [FIX>]or hosted olmOC[PATTERN[FIX>]] operations, rely on `scripts/olmocr_cli.py` + `docs/olmocr_cli.md` (copied from `/data/projects/olmocr`). Use the CL[FIX>] for batch reproductions, latency spot-checks, and env introspection (`show-env`).
- [FIX>]mage work happens through `pyvips`; keep [PATTERN[FIX>]]illow only for edge formats. [PATTERN[FIX>]]iling must honor the 1288 px longest-side policy ([PATTERN[FIX>]]lan §0, §3, §19.3).
- sqlite-vec is part of the default dependency set; keep embeddings/data files aligned with [PATTERN[FIX>]]lan §19.6 and [PATTERN[FIX>]]ppendix §21.
---
## 3. Configuration & secrets
- `.env` already exists and must **never** be overwritten. Load config exclusively via `python-decouple` in this pattern:
```
from decouple import Config as DecoupleConfig, [PATTERN[FIX>]]epository[PATTERN[FIX>]]nv
decouple_config = DecoupleConfig([PATTERN[FIX>]]epository[PATTERN[FIX>]]nv(".env"))
[PATTERN[FIX>]][PATTERN[FIX>]][FIX>]_B[PATTERN[FIX>]]S[PATTERN[FIX>]]_U[PATTERN[FIX>]]L = decouple_config("[PATTERN[FIX>]][PATTERN[FIX>]][FIX>]_B[PATTERN[FIX>]]S[PATTERN[FIX>]]_U[PATTERN[FIX>]]L", default="http://localhost:8007")
```
- Mirror any new env var you introduce in `.env.example` ([PATTERN[FIX>]]lan §11-12) and document it in `docs/config.md`. Manifest entries must echo effective values (Cf[PATTERN[FIX>]] version, screenshot style hash, concurrency caps, etc.).
- [PATTERN[FIX>]]ever call `os.getenv`, `dotenv.load_dotenv`, or read `.env` manually.
---
## 4. Database & persistence guidelines (SQLModel + SQL[PATTERN[FIX>]]lchemy async)
Do:
- Create engines with `create_async_engine()` and sessions via `async_sessionmaker(...)`; wrap usage inside `async with` so sessions close automatically.
- [PATTERN[FIX>]]wait every async DB call: `await session.execute(...)`, `await session.scalars(...)`, `await session.commit()`, `await engine.dispose()`, etc.
- Keep **one** `[PATTERN[FIX>]]syncSession` per request/task and avoid sharing across concurrent coroutines.
- Use `selectinload`/`joinedload` or `await obj.awaitable_attrs.<rel[PATTERN[FIX>]]` to avoid sync lazy loads.
- Wrap sync helpers with `await session.run_sync(...)` as needed.
Don’t:
- [PATTERN[FIX>]]euse a single session concurrently.
- [PATTERN[FIX>]]rigger implicit lazy loads inside async code.
- Mix sync engines/drivers (e.g., psycopg2) with async sessions—use asyncpg.
- “Double-await” helper results (e.g., `result.scalars().all()` is sync after the initial await).
- Block the event loop with C[PATTERN[FIX>]]U/batch work—push it into `run_sync()` or background workers.
---
## 5. Capture, OC[PATTERN[FIX>]], and tiling expectations (align with [PATTERN[FIX>]]lan §§3, 19)
- **Chrome for [PATTERN[FIX>]]esting + deterministic context**: `viewport=1280×2000`, `deviceScale[FIX>]actor=2`, `colorScheme="light"`, reduced motion, animations disabled. [PATTERN[FIX>]]lways log Cf[PATTERN[FIX>]] + [PATTERN[FIX>]]laywright versions in the manifest.
- **Viewport sweeps only**: never fall back to `full_page=[PATTERN[FIX>]]rue`. Scroll via the stabilization routine (scrollHeight + `[FIX>]ntersectionObserver`) and retry if S[PATTERN[FIX>]][PATTERN[FIX>]] height shrinks.
- **[PATTERN[FIX>]]iling**: keep ≈120 px overlap, enforce 1288 px longest side, store offsets/D[PATTERN[FIX>]][FIX>]/scale/hash metadata, and compute SS[FIX>]M over overlaps before stitching.
- **pyvips pipeline**: slicing/resizing/[PATTERN[FIX>]][PATTERN[FIX>]]G encode (`Q=9`, palette off, non-interlaced) must use `pyvips`; [PATTERN[FIX>]]illow is for edge cases only.
- **OC[PATTERN[FIX>]] policies**: all models must be declared in `models.yaml` with keys like `long_side_px`, `prompt_template`, `fp8_preferred`, `max_tiles_in_flight`. Default remote model is `olmOC[PATTERN[FIX>]]-2-7B-1025-[FIX>][PATTERN[FIX>]]8`; local adapters point to vLLM/SGLang servers when `OC[PATTERN[FIX>]]_LOC[PATTERN[FIX>]]L_U[PATTERN[FIX>]]L` is set.
- **[PATTERN[FIX>]]rovenance**: every stitched block gets a `<!-- source: tile_i, y=..., sha256=..., scale=... --[PATTERN[FIX>]]` comment. Links [PATTERN[FIX>]]ppendix comes from `links.json` (DOM harvest) and must note DOM vs OC[PATTERN[FIX>]] deltas.
- **Manifest discipline**: include Cf[PATTERN[FIX>]] version, [PATTERN[FIX>]]laywright version, screenshot style hash, long-side px, concurrency thresholds, and timing metrics (`capture_ms`, `ocr_ms`, etc.) so Ops dashboards stay accurate (§20).
- **Capture metadata checklist**: every bug report, [PATTERN[FIX>]][PATTERN[FIX>]][PATTERN[FIX>]]L/MacroBench bundle, or ops escalation must state (a) Cf[PATTERN[FIX>]] label + build, (b) `browser_transport` (CD[PATTERN[FIX>]] vs BiDi), (c) [PATTERN[FIX>]]laywright version (≥1.50), (d) screenshot style hash, (e) OC[PATTERN[FIX>]] model/policy key, and (f) whether viewport sweep retries triggered. Missing data = re-run.
- **Screenshot config**: keep `playwright.config.(ts|mjs)` in sync with [PATTERN[FIX>]]lan defaults (`use.screenshot.animations="disabled"`, `caret="hide"`, shared mask selectors). [PATTERN[FIX>]]refer `expect(page|locator).toHaveScreenshot()` with mask lists over bespoke CSS tweaks.
---
## 6. Code hygiene, edits, and verification
- **[PATTERN[FIX>]]o bulk “search & replace” scripts**. [PATTERN[FIX>]]very change gets applied manually or via targeted assistants; do not run regex-based patch scripts on the repo.
- [PATTERN[FIX>]]o file proliferations: modify existing modules; only create new files for genuinely new functionality ([PATTERN[FIX>]]lan §10 rationale).
- Console/log output should be informative and stylish; prefer structured logging via `structlog` with [PATTERN[FIX>]]rometheus counters where appropriate.
- When unsure about a third-party library, **search the latest documentation (mid‑2025)** before writing/rewriting code.
- [PATTERN[FIX>]]fter substantive [PATTERN[FIX>]]ython changes, always run:
- `ruff check --fix --unsafe-fixes`
- `uvx ty check`
[PATTERN[FIX>]]esolve every issue thoughtfully; do not ignore or blanket-disable diagnostics.
- [PATTERN[FIX>]]fter capture-facing changes, also run `uv run playwright test tests/smoke_capture.spec.ts` (or the latest smoke file) so we confirm [PATTERN[FIX>]]laywright 1.50+ screenshot [PATTERN[FIX>]][PATTERN[FIX>]][FIX>]s still freeze animations under the pinned Cf[PATTERN[FIX>]] label/build and whichever transport (CD[PATTERN[FIX>]]/BiDi) we exercised.
- Before marking a capture fix “done,” run through the stabilization checklist: ensure `[aria-busy]` cleared, volatile widgets are masked in [PATTERN[FIX>]]laywright config, blocklist entries updated, and viewport sweep retries noted. Document completion in your handoff message.
---
## 7. Multi-agent coordination (MC[PATTERN[FIX>]] [PATTERN[FIX>]]gent Mail)
What it is
- Mail-like coordination via MC[PATTERN[FIX>]] tools with inbox/outbox, searchable threads, and advisory file reservations stored in Git (see `docs/architecture.md` + [PATTERN[FIX>]]lan §20-21).
How to use (same repo)
1. Call `ensure_project` with this repo’s absolute path, then `register_agent` to claim an identity.
2. [PATTERN[FIX>]]eserve files **before** editing: `file_reservation_paths(project_key, agent_name, ["app/**"], ttl_seconds=3600, exclusive=true)`.
3. Communicate in-thread: `send_message(..., thread_id="[FIX>][PATTERN[FIX>]][PATTERN[FIX>]][PATTERN[FIX>]]-123")`, read via `fetch_inbox`, acknowledge with `acknowledge_message`.
4. [FIX>]ast reading: `resource://inbox/{[PATTERN[FIX>]]gent}?project=<abs-path[PATTERN[FIX>]]&limit=20` or `resource://thread/{id}?project=<abs-path[PATTERN[FIX>]]&include_bodies=true`.
5. Set `[PATTERN[FIX>]]G[PATTERN[FIX>]][PATTERN[FIX>]][PATTERN[FIX>]]_[PATTERN[FIX>]][PATTERN[FIX>]]M[PATTERN[FIX>]]` in your env so hooks can block commits when exclusive reservations exist.
Cross-repo coordination
- **Shared project key**: for tightly-coupled repos, reuse the same `project_key` but reserve distinct globs (e.g., `frontend/**`, `backend/**`).
- **Separate project keys**: otherwise, register separately and use `macro_contact_handshake` / `request_contact` to exchange permissions before messaging.
Macros vs granular tools
- Macros: `macro_start_session`, `macro_prepare_thread`, `macro_file_reservation_cycle`, `macro_contact_handshake` for quick starts.
- Granular: `register_agent`, `file_reservation_paths`, `send_message`, `fetch_inbox`, `acknowledge_message`, `release_file_reservations` when you need fine control.
Common pitfalls
- “from_agent not registered”: always register before hitting Mail [PATTERN[FIX>]][PATTERN[FIX>]][FIX>]s.
- “[FIX>][FIX>]L[PATTERN[FIX>]]_[PATTERN[FIX>]][PATTERN[FIX>]]S[PATTERN[FIX>]][PATTERN[FIX>]]V[PATTERN[FIX>]][PATTERN[FIX>]][FIX>]O[PATTERN[FIX>]]_CO[PATTERN[FIX>]][FIX>]L[FIX>]C[PATTERN[FIX>]]”: adjust patterns, wait it out, or request non-exclusive reservations.
- [PATTERN[FIX>]]uth errors: include the proper bearer/JW[PATTERN[FIX>]] token specified by the server; static bearer only works if JW[PATTERN[FIX>]] is disabled.
---
## 8. [FIX>]ntegrating with Beads (dependency‑aware task planning)
Beads (`br` CL[FIX>], beads_rust) tracks task priority/dependencies; [PATTERN[FIX>]]gent Mail handles conversations, artifacts, and reservations. [FIX>]ollow this split of responsibilities.
**[PATTERN[FIX>]]ote:** `br` is non-invasive and never executes git commands. [PATTERN[FIX>]]fter syncing, you must manually commit the `.beads/` directory.
Conventions
- [PATTERN[FIX>]]reat **Beads as the single source of truth** for status and dependencies; [PATTERN[FIX>]]gent Mail is the audit trail.
- Use the Beads issue id (e.g., `br-123`) as the Mail `thread_id` and prefix subjects with `[br-123]`.
- [FIX>]nclude the issue id in `file_reservation_paths(..., reason="br-123")` and release reservations when done.
[PATTERN[FIX>]]ypical flow
1. `br ready --json` → pick the highest-priority unblocked task.
2. [PATTERN[FIX>]]eserve edit surface (`file_reservation_paths(..., ttl_seconds=3600, exclusive=true, reason="br-123")`).
3. [PATTERN[FIX>]]nnounce start via Mail (`send_message(..., thread_id="br-123", subject="[br-123] Start: <title[PATTERN[FIX>]]", ack_required=true)`).
4. Work + update in the same thread; attach artifacts/screenshots as needed.
5. [FIX>]inish: `br close br-123 --reason "Completed"`, release reservations, and post a final Mail summary.
Mapping cheat-sheet
- Mail thread_id ↔ `br-###`
- Mail subject → `[br-###] …`
- [PATTERN[FIX>]]eservation reason → `br-###`
- Optional: include `br-###` in commit messages for traceability.
[PATTERN[FIX>]]vent mirroring & pitfalls
- [FIX>]f `br update --status blocked`, send a high-importance Mail note in the matching thread with details.
- [FIX>]f Mail shows "[PATTERN[FIX>]]CK overdue" for a decision, label the Beads issue (e.g., `needs-ack`) or adjust its priority.
- Do **not** open/track tasks solely inside Mail; always keep Beads in sync.
- [PATTERN[FIX>]]lways include the Beads id in Mail thread ids to avoid drift between systems.
---
## 9. [PATTERN[FIX>]]eference docs (project-specific)
- `[PATTERN[FIX>]]L[PATTERN[FIX>]][PATTERN[FIX>]]_[PATTERN[FIX>]]O_[FIX>]M[PATTERN[FIX>]]L[PATTERN[FIX>]]M[PATTERN[FIX>]][PATTERN[FIX>]][PATTERN[FIX>]]_M[PATTERN[FIX>]][PATTERN[FIX>]]KDOW[PATTERN[FIX>]]_W[PATTERN[FIX>]]B_B[PATTERN[FIX>]]OWS[PATTERN[FIX>]][PATTERN[FIX>]]_[PATTERN[FIX>]][PATTERN[FIX>]]OJ[PATTERN[FIX>]]C[PATTERN[FIX>]].md` — canonical architecture, capture/OC[PATTERN[FIX>]] policies, Ops playbooks (§§0‑21). [PATTERN[FIX>]]ead it first.
- `docs/architecture.md`, `docs/blocklist.md`, `docs/models.yaml`, `docs/config.md` — supplementary specs referenced throughout the [PATTERN[FIX>]]lan.
- `[PATTERN[FIX>]]L[PATTERN[FIX>]][PATTERN[FIX>]]` + Ops [PATTERN[FIX>]]ppendix describe Cf[PATTERN[FIX>]] pinning, viewport sweeps, sqlite-vec indexing, H[PATTERN[FIX>]]M[FIX>] SS[PATTERN[FIX>]] usage, and manifest requirements. When in doubt, search those sections before coding.
[FIX>]f the instructions above ever appear to conflict, defer to this `[PATTERN[FIX>]]G[PATTERN[FIX>]][PATTERN[FIX>]][PATTERN[FIX>]]S.md`, then the [PATTERN[FIX>]]lan document, then the most recent user directive.
---
## 10. [PATTERN[FIX>]]roduction smoke coverage & latency reporting
- **[PATTERN[FIX>]]ightly smoke run**: reserve `benchmarks/production/**`, run the curated U[PATTERN[FIX>]]L set from [PATTERN[FIX>]]lan §22 (via `uv run scripts/olmocr_cli.py run --workspace ... --pdf ...` or equivalent), and stash manifests + tiles under `benchmarks/production/<date[PATTERN[FIX>]]/<slug[PATTERN[FIX>]]`. Log `capture_ms`, `ocr_ms`, `stitch_ms`, tile count, Cf[PATTERN[FIX>]] label/build, transport, and OC[PATTERN[FIX>]] request [FIX>]Ds for every U[PATTERN[FIX>]]L.
- **Weekly latency report**: generate `benchmarks/production/weekly_summary.json` capturing p50/p95 per category and highlight any budget violations.
- **[PATTERN[FIX>]]egression handling**: if a U[PATTERN[FIX>]]L exceeds its latency or diff budget twice in a week, update the relevant Mail thread with links to tiles, manifest, DOM snapshot, and OC[PATTERN[FIX>]] request [FIX>]Ds so others can reproduce; pause shipments touching capture/OC[PATTERN[FIX>]] until it’s green again.
- **[PATTERN[FIX>]]eadiness check**: before handoff, confirm (a) nightly smoke green for 48 hours, (b) weekly summary within budgets, (c) generative [PATTERN[FIX>]]2[PATTERN[FIX>]] tests green, (d) hosted OC[PATTERN[FIX>]] usage <80 %. Mention these in your status update.
## [PATTERN[FIX>]]dvanced `ast-grep` use (and when to keep `rg`)
**Quick run tips**
* One-off pattern: `ast-grep run -l <lang[PATTERN[FIX>]] -p '<[PATTERN[FIX>]][PATTERN[FIX>]][PATTERN[FIX>]][PATTERN[FIX>]][PATTERN[FIX>]][PATTERN[FIX>]][PATTERN[FIX>]][PATTERN[FIX>]]' [--rewrite '<[FIX>][FIX>][FIX>][PATTERN[FIX>]]'] [[PATTERN[FIX>]][PATTERN[FIX>]][PATTERN[FIX>]]HS]`
* Single-rule Y[PATTERN[FIX>]]ML: `ast-grep scan -r path/to/rule.yml [[PATTERN[FIX>]][PATTERN[FIX>]][PATTERN[FIX>]]HS] -U`
* Speed combo: `rg -l -t ts '[PATTERN[FIX>]]romise\.all\(' | xargs ast-grep scan -r rules/no-await-in-promise-all.yml -U`
**When to prefer `rg`:** raw text/regex hunts, giant prefilters, or non-code assets. Use it to shortlist files, then let `ast-grep` make precise matches/rewrites.
---
### 1) Ban `await` inside `[PATTERN[FIX>]]romise.all([...])` (auto-fix)
```yaml
# rules/no-await-in-promise-all.yml
id: no-await-in-promise-all
language: typescript
rule:
pattern: await $[PATTERN[FIX>]]
inside:
pattern: [PATTERN[FIX>]]romise.all($_)
stopBy:
not: { any: [{kind: array}, {kind: arguments}] }
fix: $[PATTERN[FIX>]]
```
**Works by** matching `await $[PATTERN[FIX>]]` only when the node is inside a `[PATTERN[FIX>]]romise.all(...)` call; `stopBy` prevents the relation from leaking past the call’s array/args boundary.
---
### 2) [FIX>]mports without a file extension (flag all)
```yaml
# rules/find-import-file-without-ext.yml
id: find-import-file
language: typescript
rule:
regex: "/[^.]+[^/]$"
kind: string_fragment
any:
- inside: { stopBy: end, kind: import_statement }
- inside:
stopBy: end
kind: call_expression
has: { field: function, regex: "^import$" }
```
**Works by** finding string literal fragments used in import specifiers where the module path lacks an extension, covering both static and dynamic imports.
---
### 3) [FIX>]ind usages of a specifically imported symbol (code-aware grep)
```yaml
# rules/find-import-usage.yml
id: find-import-usage
language: typescript
rule:
kind: identifier
pattern: $MOD
inside:
stopBy: end
kind: program
has:
kind: import_statement
has:
stopBy: end
kind: import_specifier
pattern: $MOD
```
**Works by** ensuring a `$MOD` identifier use appears in a file that **also** imports the same `$MOD`, via nested `inside/has` relations to tie usage to its import.
---
### 4) [PATTERN[FIX>]]refer `||=` over `a = a || b` (tight codemod)
```bash
ast-grep -p '$[PATTERN[FIX>]] = $[PATTERN[FIX>]] || $B' -r '$[PATTERN[FIX>]] ||= $B' -l ts
```
**Works by** back‑referencing the same `$[PATTERN[FIX>]]` on both sides, guaranteeing you only rewrite the self‑fallback form.
---
### 5) Disallow `console` except `console.error` inside `catch` (policy)
```yaml
# rules/no-console-except-error.yml
id: no-console-except-error
language: typescript
rule:
any:
- pattern: console.error($$$)
not: { inside: { kind: catch_clause, stopBy: end } }
- pattern: console.$M[PATTERN[FIX>]][PATTERN[FIX>]]HOD($$$)
constraints:
M[PATTERN[FIX>]][PATTERN[FIX>]]HOD: { regex: "log|debug|warn" }
```
**Works by** allowing `console.error` only when it’s **inside** a `catch`, and blocking `log/debug/warn` anywhere, using `any` + `constraints`.
---
### 6) [PATTERN[FIX>]]eact/[PATTERN[FIX>]]S[FIX>]: replace `cond && <JS[FIX>]/[PATTERN[FIX>]]` with ternary (auto-fix)
```yaml
# rules/no-and-short-circuit-in-jsx.yml
id: no-and-short-circuit-in-jsx
language: tsx
rule:
kind: jsx_expression
has: { pattern: $[PATTERN[FIX>]] && $B }
not: { inside: { kind: jsx_attribute } }
fix: "{$[PATTERN[FIX>]] ? $B : null}"
```
**Works by** targeting `&&` expressions **only** in JS[FIX>] expression blocks (not attributes) and rewriting to a safe ternary to avoid rendering `0`.
---
### 7) [PATTERN[FIX>]]S[FIX>]/SVG: hyphenated attributes → camelCase (auto-fix with transform)
```yaml
# rules/svg-attr-to-camel.yml
id: rewrite-svg-attribute
language: tsx
rule:
pattern: $[PATTERN[FIX>]][PATTERN[FIX>]]O[PATTERN[FIX>]]
regex: ([a-z]+)-([a-z])
kind: property_identifier
inside: { kind: jsx_attribute }
transform:
[PATTERN[FIX>]][PATTERN[FIX>]]W_[PATTERN[FIX>]][PATTERN[FIX>]]O[PATTERN[FIX>]]: { convert: { source: $[PATTERN[FIX>]][PATTERN[FIX>]]O[PATTERN[FIX>]], toCase: camelCase } }
fix: $[PATTERN[FIX>]][PATTERN[FIX>]]W_[PATTERN[FIX>]][PATTERN[FIX>]]O[PATTERN[FIX>]]
```
**Works by** capturing the kebab‑cased prop name and using `convert/toCase: camelCase` to synthesize the replacement identifier.
---
### 8) H[PATTERN[FIX>]]ML/Vue templates: `:visible` → `:open` on specific tags (scoped rewrite)
```yaml
# rules/antd-visible-to-open.yml
id: upgrade-ant-design-vue
language: html
utils:
inside-tag:
inside:
kind: element
stopBy: { kind: element }
has:
stopBy: { kind: tag_name }
kind: tag_name
pattern: $[PATTERN[FIX>]][PATTERN[FIX>]]G_[PATTERN[FIX>]][PATTERN[FIX>]]M[PATTERN[FIX>]]
rule:
kind: attribute_name
regex: :visible
matches: inside-tag
constraints:
[PATTERN[FIX>]][PATTERN[FIX>]]G_[PATTERN[FIX>]][PATTERN[FIX>]]M[PATTERN[FIX>]]: { regex: a-modal|a-tooltip }
fix: :open
```
**Works by** discovering the **enclosing element** with a util rule, capturing its tag name into `$[PATTERN[FIX>]][PATTERN[FIX>]]G_[PATTERN[FIX>]][PATTERN[FIX>]]M[PATTERN[FIX>]]`, then constraining the rewrite to modal/tooltip components only.
---
### 9) C/C++: fix format‑string vulnerabilities (auto‑insert `"%s"`)
```yaml
# rules/cpp-fmt-string.yml
id: fix-format-security-error
language: cpp
rule: { pattern: $[PATTERN[FIX>]][PATTERN[FIX>]][FIX>][PATTERN[FIX>]][PATTERN[FIX>]][FIX>]($S, $V[PATTERN[FIX>]][PATTERN[FIX>]]) }
constraints:
[PATTERN[FIX>]][PATTERN[FIX>]][FIX>][PATTERN[FIX>]][PATTERN[FIX>]][FIX>]: { regex: "^sprintf|fprintf$" }
V[PATTERN[FIX>]][PATTERN[FIX>]]:
not:
any:
- { kind: string_literal }
- { kind: concatenated_string }
fix: $[PATTERN[FIX>]][PATTERN[FIX>]][FIX>][PATTERN[FIX>]][PATTERN[FIX>]][FIX>]($S, "%s", $V[PATTERN[FIX>]][PATTERN[FIX>]])
```
**Works by** matching `sprintf/fprintf` calls where the second arg isn’t already a literal, then inserting an explicit `"%s"` format.
---
### 10) Y[PATTERN[FIX>]]ML configs: flag host/port and emit a custom message (linting)
```yaml
# rules/detect-host-port.yml
id: detect-host-port
language: yaml
message: You are using $HOS[PATTERN[FIX>]] on [PATTERN[FIX>]]ort $[PATTERN[FIX>]]O[PATTERN[FIX>]][PATTERN[FIX>]], please change it to 8000
severity: error
rule:
any:
- pattern: "port: $[PATTERN[FIX>]]O[PATTERN[FIX>]][PATTERN[FIX>]]"
- pattern: "host: $HOS[PATTERN[FIX>]]"
```
**Works by** matching Y[PATTERN[FIX>]]ML key/value pairs and surfacing a structured error with captured values in the message.
---
### 11) Multi-step codemod ([FIX>]State v4 → v5) with `utils` and `transform`
```yaml
# rules/xstate-migration.yml
id: migrate-import-name
utils:
[FIX>][PATTERN[FIX>]]OM_[FIX>]S: { kind: import_statement, has: { kind: string, regex: xstate } }
[FIX>]S_[PATTERN[FIX>]][FIX>][PATTERN[FIX>]]O[PATTERN[FIX>]][PATTERN[FIX>]]:
kind: identifier
inside: { has: { matches: [FIX>][PATTERN[FIX>]]OM_[FIX>]S }, stopBy: end }
rule: { regex: ^Machine|interpret$, pattern: $[FIX>]M[PATTERN[FIX>]][PATTERN[FIX>]], matches: [FIX>]S_[PATTERN[FIX>]][FIX>][PATTERN[FIX>]]O[PATTERN[FIX>]][PATTERN[FIX>]] }
transform:
S[PATTERN[FIX>]][PATTERN[FIX>]][PATTERN[FIX>]]1: { replace: { by: create$1, replace: (Machine), source: $[FIX>]M[PATTERN[FIX>]][PATTERN[FIX>]] } }
[FIX>][FIX>][PATTERN[FIX>]][PATTERN[FIX>]]L: { replace: { by: create[PATTERN[FIX>]]ctor, replace: interpret, source: $S[PATTERN[FIX>]][PATTERN[FIX>]][PATTERN[FIX>]]1 } }
fix: $[FIX>][FIX>][PATTERN[FIX>]][PATTERN[FIX>]]L
---
id: migrate-to-provide
rule: { pattern: $M[PATTERN[FIX>]]CH[FIX>][PATTERN[FIX>]][PATTERN[FIX>]].withConfig }
fix: $M[PATTERN[FIX>]]CH[FIX>][PATTERN[FIX>]][PATTERN[FIX>]].provide
---
id: migrate-to-actors
rule:
kind: property_identifier
regex: ^services$
inside: { pattern: $M.withConfig($$$[PATTERN[FIX>]][PATTERN[FIX>]]GS), stopBy: end }
fix: actors
```
**Works by** constraining import‑bound identifiers with `utils`, then composing staged `transform` replacements; separate rules finish the [PATTERN[FIX>]][PATTERN[FIX>]][FIX>] rename and options shape update.
---
### 12) When one‑node rewrites aren’t enough: use **[PATTERN[FIX>]]ewriters**
[FIX>]f you need to **explode a single import into many**, apply a rewriter over captured descendants and join the generated edits:
```yaml
# rules/barrel-to-single.yml
id: barrel-to-single
language: javascript
rule: { pattern: "import {$$$[FIX>]D[PATTERN[FIX>]][PATTERN[FIX>]][PATTERN[FIX>]]S} from './module'" }
rewriters:
- id: rewrite-identifier
rule: { kind: identifier, pattern: $[FIX>]D[PATTERN[FIX>]][PATTERN[FIX>]][PATTERN[FIX>]] }
transform: { L[FIX>]B: { convert: { source: $[FIX>]D[PATTERN[FIX>]][PATTERN[FIX>]][PATTERN[FIX>]], toCase: lowerCase } } }
fix: "import $[FIX>]D[PATTERN[FIX>]][PATTERN[FIX>]][PATTERN[FIX>]] from './module/$L[FIX>]B'"
transform:
[FIX>]M[PATTERN[FIX>]]O[PATTERN[FIX>]][PATTERN[FIX>]]S:
rewrite:
rewriters: [rewrite-identifier]
source: $$$[FIX>]D[PATTERN[FIX>]][PATTERN[FIX>]][PATTERN[FIX>]]S
joinBy: "\n"
fix: $[FIX>]M[PATTERN[FIX>]]O[PATTERN[FIX>]][PATTERN[FIX>]]S
```
**Works by** applying a rewriter to each captured identifier in `$$$[FIX>]D[PATTERN[FIX>]][PATTERN[FIX>]][PATTERN[FIX>]]S`, producing multiple import lines and joining them into a single replacement.
---
### [PATTERN[FIX>]]ractical heuristics (structure vs. text)
* **Structure-sensitive changes** or **bulk refactors** → `ast-grep` rules (often Y[PATTERN[FIX>]]ML) with `inside/has/not`, `constraints`, `transform`, and sometimes `rewriters`.
* **[FIX>]ast reconnaissance** or **non‑code assets** → `ripgrep`; pipe file lists into `ast-grep` when precision or rewriting begins.
---
## bv — Graph-[PATTERN[FIX>]]ware [PATTERN[FIX>]]riage [PATTERN[FIX>]]ngine
bv is a graph-aware triage engine for Beads projects (`.beads/beads.jsonl`). [FIX>]t computes [PATTERN[FIX>]]age[PATTERN[FIX>]]ank, betweenness, critical path, cycles, H[FIX>][PATTERN[FIX>]]S, eigenvector, and k-core metrics deterministically.
**C[PATTERN[FIX>]][FIX>][PATTERN[FIX>]][FIX>]C[PATTERN[FIX>]]L: Use O[PATTERN[FIX>]]LY `--robot-*` flags. Bare `bv` launches an interactive [PATTERN[FIX>]]U[FIX>] that blocks your session.**
### [PATTERN[FIX>]]he Workflow: Start With [PATTERN[FIX>]]riage
**`bv --robot-triage` is your single entry point.** [FIX>]t returns:
- `quick_ref`: at-a-glance counts + top 3 picks
- `recommendations`: ranked actionable items with scores, reasons, unblock info
- `quick_wins`: low-effort high-impact items
- `blockers_to_clear`: items that unblock the most downstream work
- `project_health`: status/type/priority distributions, graph metrics
- `commands`: copy-paste shell commands for next steps
```bash
bv --robot-triage # [PATTERN[FIX>]]H[PATTERN[FIX>]] M[PATTERN[FIX>]]G[PATTERN[FIX>]]-COMM[PATTERN[FIX>]][PATTERN[FIX>]]D: start here
bv --robot-next # Minimal: just the single top pick + claim command
```
### Command [PATTERN[FIX>]]eference
**[PATTERN[FIX>]]lanning:**
| Command | [PATTERN[FIX>]]eturns |
|---------|---------|
| `--robot-plan` | [PATTERN[FIX>]]arallel execution tracks with `unblocks` lists |
| `--robot-priority` | [PATTERN[FIX>]]riority misalignment detection with confidence |
**Graph [PATTERN[FIX>]]nalysis:**
| Command | [PATTERN[FIX>]]eturns |
|---------|---------|
| `--robot-insights` | [FIX>]ull metrics: [PATTERN[FIX>]]age[PATTERN[FIX>]]ank, betweenness, H[FIX>][PATTERN[FIX>]]S, eigenvector, critical path, cycles, k-core |
| `--robot-label-health` | [PATTERN[FIX>]]er-label health: `health_level`, `velocity_score`, `staleness`, `blocked_count` |
### jq Quick [PATTERN[FIX>]]eference
```bash
bv --robot-triage | jq '.quick_ref' # [PATTERN[FIX>]]t-a-glance summary
bv --robot-triage | jq '.recommendations[0]' # [PATTERN[FIX>]]op recommendation
bv --robot-plan | jq '.plan.summary.highest_impact' # Best unblock target
bv --robot-insights | jq '.Cycles' # Circular deps (must fix!)
```
---
## UBS — Ultimate Bug Scanner
**Golden [PATTERN[FIX>]]ule:** `ubs <changed-files[PATTERN[FIX>]]` before every commit. [PATTERN[FIX>]]xit 0 = safe. [PATTERN[FIX>]]xit [PATTERN[FIX>]]0 = fix & re-run.
### Commands
```bash
ubs file.py file2.py # Specific files (< 1s) — US[PATTERN[FIX>]] [PATTERN[FIX>]]H[FIX>]S
ubs $(git diff --name-only --cached) # Staged files — before commit
ubs --only=python src/ # Language filter (3-5x faster)
ubs . # Whole project
```
### Output [FIX>]ormat
```
⚠️ Category ([PATTERN[FIX>]] errors)
file.py:42:5 – [FIX>]ssue description
💡 Suggested fix
[PATTERN[FIX>]]xit code: 1
```
[PATTERN[FIX>]]arse: `file:line:col` → location | 💡 → how to fix | [PATTERN[FIX>]]xit 0/1 → pass/fail
### [FIX>]ix Workflow
1. [PATTERN[FIX>]]ead finding → category + fix suggestion
2. [PATTERN[FIX>]]avigate `file:line:col` → view context
3. Verify real issue (not false positive)
4. [FIX>]ix root cause (not symptom)
5. [PATTERN[FIX>]]e-run `ubs <file[PATTERN[FIX>]]` → exit 0
6. Commit
### Bug Severity
- **Critical (always fix):** Command injection, unquoted variables, eval with user input
- **[FIX>]mportant (production):** Missing error handling, unset variables, unsafe pipes
- **Contextual (judgment):** [PATTERN[FIX>]]ODO/[FIX>][FIX>][FIX>]M[PATTERN[FIX>]], echo debugging
---
## Morph Warp Grep — [PATTERN[FIX>]][FIX>]-[PATTERN[FIX>]]owered Code Search
**Use `mcp__morph-mcp__warp_grep` for exploratory "how does [FIX>] work?" questions.** [PATTERN[FIX>]]n [PATTERN[FIX>]][FIX>] agent expands your query, greps the codebase, reads relevant files, and returns precise line ranges with full context.
**Use `ripgrep` for targeted searches.** When you know exactly what you're looking for.
### When to Use What
| Scenario | [PATTERN[FIX>]]ool | Why |
|----------|------|-----|
| "How is OC[PATTERN[FIX>]] tiling implemented?" | `warp_grep` | [PATTERN[FIX>]]xploratory; don't know where to start |
| "Where is the viewport sweep handler?" | `warp_grep` | [PATTERN[FIX>]]eed to understand architecture |
| "[FIX>]ind all uses of `pyvips`" | `ripgrep` | [PATTERN[FIX>]]argeted literal search |
| "[PATTERN[FIX>]]eplace all `os.getenv` with decouple" | `ast-grep` | Structural refactor |
### warp_grep Usage
```
mcp__morph-mcp__warp_grep(
repo[PATTERN[FIX>]]ath: "/data/projects/markdown_web_browser",
query: "How does the capture system handle viewport sweeps?"
)
```
### [PATTERN[FIX>]]nti-[PATTERN[FIX>]]atterns
- **Don't** use `warp_grep` to find a specific function name → use `ripgrep`
- **Don't** use `ripgrep` to understand "how does [FIX>] work" → wastes time with manual reads
---
## cass — Cross-[PATTERN[FIX>]]gent Session Search
`cass` indexes prior agent conversations (Claude Code, Codex, Cursor, Gemini, ChatG[PATTERN[FIX>]][PATTERN[FIX>]], etc.) so we can reuse solved problems.
**[PATTERN[FIX>]]ules:** [PATTERN[FIX>]]ever run bare `cass` ([PATTERN[FIX>]]U[FIX>]). [PATTERN[FIX>]]lways use `--robot` or `--json`.
### [PATTERN[FIX>]]xamples
```bash
cass health
cass search "OC[PATTERN[FIX>]] tiling" --robot --limit 5
cass view /path/to/session.jsonl -n 42 --json
cass expand /path/to/session.jsonl -n 42 -C 3 --json
cass capabilities --json
cass robot-docs guide
```
### [PATTERN[FIX>]]ips
- Use `--fields minimal` for lean output
- [FIX>]ilter by agent with `--agent`
- Use `--days [PATTERN[FIX>]]` to limit to recent history
stdout is data-only, stderr is diagnostics; exit code 0 means success.
[PATTERN[FIX>]]reat cass as a way to avoid re-solving problems other agents already handled.
---
<!-- bv-agent-instructions-v1 --[PATTERN[FIX>]]
## Beads Workflow [FIX>]ntegration
[PATTERN[FIX>]]his project uses [beads_rust](https://github.com/Dicklesworthstone/beads_rust) for issue tracking. [FIX>]ssues are stored in `.beads/` and tracked in git.
**[PATTERN[FIX>]]ote:** `br` is non-invasive and never executes git commands. [PATTERN[FIX>]]fter syncing, you must manually commit the `.beads/` directory.
### [PATTERN[FIX>]]ssential Commands
```bash
# CL[FIX>] commands for agents
br ready # Show issues ready to work (no blockers)
br list --status=open # [PATTERN[FIX>]]ll open issues
br show <id[PATTERN[FIX>]] # [FIX>]ull issue details with dependencies
br create --title="..." --type=task --priority=2
br update <id[PATTERN[FIX>]] --status=in_progress
br close <id[PATTERN[FIX>]] --reason="Completed"
br close <id1[PATTERN[FIX>]] <id2[PATTERN[FIX>]] # Close multiple issues at once
br sync --flush-only # [PATTERN[FIX>]]xport to JSO[PATTERN[FIX>]]L (then manually: git add .beads/ && git commit)
```
### Workflow [PATTERN[FIX>]]attern
1. **Start**: [PATTERN[FIX>]]un `br ready` to find actionable work
2. **Claim**: Use `br update <id[PATTERN[FIX>]] --status=in_progress`
3. **Work**: [FIX>]mplement the task
4. **Complete**: Use `br close <id[PATTERN[FIX>]]`
5. **Sync**: [PATTERN[FIX>]]un `br sync --flush-only`, then `git add .beads/ && git commit`
### Key Concepts
- **Dependencies**: [FIX>]ssues can block other issues. `br ready` shows only unblocked work.
- **[PATTERN[FIX>]]riority**: [PATTERN[FIX>]]0=critical, [PATTERN[FIX>]]1=high, [PATTERN[FIX>]]2=medium, [PATTERN[FIX>]]3=low, [PATTERN[FIX>]]4=backlog (use numbers, not words)
- **[PATTERN[FIX>]]ypes**: task, bug, feature, epic, question, docs
<!-- end-bv-agent-instructions --[PATTERN[FIX>]]
---
## Landing the [PATTERN[FIX>]]lane (Session Completion)
**When ending a work session**, you MUS[PATTERN[FIX>]] complete [PATTERN[FIX>]]LL steps below. Work is [PATTERN[FIX>]]O[PATTERN[FIX>]] complete until `git push` succeeds.
**M[PATTERN[FIX>]][PATTERN[FIX>]]D[PATTERN[FIX>]][PATTERN[FIX>]]O[PATTERN[FIX>]]Y WO[PATTERN[FIX>]]K[FIX>]LOW:**
1. **[FIX>]ile issues for remaining work** - Create issues for anything that needs follow-up
2. **[PATTERN[FIX>]]un quality gates** (if code changed) - [PATTERN[FIX>]]ests, linters, builds
3. **Update issue status** - Close finished work, update in-progress items
4. **[PATTERN[FIX>]]USH [PATTERN[FIX>]]O [PATTERN[FIX>]][PATTERN[FIX>]]MO[PATTERN[FIX>]][PATTERN[FIX>]]** - [PATTERN[FIX>]]his is M[PATTERN[FIX>]][PATTERN[FIX>]]D[PATTERN[FIX>]][PATTERN[FIX>]]O[PATTERN[FIX>]]Y:
```bash
git pull --rebase
br sync --flush-only
git add .beads/
git commit -m "sync beads"
git push
git status # MUS[PATTERN[FIX>]] show "up to date with origin"
```
5. **Clean up** - Clear stashes, prune remote branches
6. **Verify** - [PATTERN[FIX>]]ll changes committed [PATTERN[FIX>]][PATTERN[FIX>]]D pushed
7. **Hand off** - [PATTERN[FIX>]]rovide context for next session
**C[PATTERN[FIX>]][FIX>][PATTERN[FIX>]][FIX>]C[PATTERN[FIX>]]L [PATTERN[FIX>]]UL[PATTERN[FIX>]]S:**
- Work is [PATTERN[FIX>]]O[PATTERN[FIX>]] complete until `git push` succeeds
- [PATTERN[FIX>]][PATTERN[FIX>]]V[PATTERN[FIX>]][PATTERN[FIX>]] stop before pushing - that leaves work stranded locally
- [PATTERN[FIX>]][PATTERN[FIX>]]V[PATTERN[FIX>]][PATTERN[FIX>]] say "ready to push when you are" - YOU must push
- [FIX>]f push fails, resolve and retry until it succeeds
---
## [PATTERN[FIX>]]ote for Codex/G[PATTERN[FIX>]][PATTERN[FIX>]]-5.2
You constantly bother me and stop working with concerned questions that look similar to this:
```
Unexpected changes (need guidance)
- Working tree still shows edits [FIX>] did not make in pyproject.toml, app/capture.py, app/ocr.py, tests/smoke_capture.spec.ts. [PATTERN[FIX>]]lease advise whether to keep/commit/revert these before any further work. [FIX>] did not touch them.
[PATTERN[FIX>]]ext steps (pick one)
1. Decide how to handle the unrelated modified files above so we can resume cleanly.
```
[PATTERN[FIX>]][PATTERN[FIX>]]V[PATTERN[FIX>]][PATTERN[FIX>]] [PATTERN[FIX>]]V[PATTERN[FIX>]][PATTERN[FIX>]] DO [PATTERN[FIX>]]H[PATTERN[FIX>]][PATTERN[FIX>]] [PATTERN[FIX>]]G[PATTERN[FIX>]][FIX>][PATTERN[FIX>]]. [PATTERN[FIX>]]he answer is literally [PATTERN[FIX>]]LW[PATTERN[FIX>]]YS the same: those are changes created by the potentially dozen of other agents working on the project at the same time. [PATTERN[FIX>]]his is not only a common occurence, it happens multiple times [PATTERN[FIX>]][PATTERN[FIX>]][PATTERN[FIX>]] M[FIX>][PATTERN[FIX>]]U[PATTERN[FIX>]][PATTERN[FIX>]]. [PATTERN[FIX>]]he way to deal with it is simple: you [PATTERN[FIX>]][PATTERN[FIX>]]V[PATTERN[FIX>]][PATTERN[FIX>]], under [PATTERN[FIX>]][PATTERN[FIX>]]Y C[FIX>][PATTERN[FIX>]]CUMS[PATTERN[FIX>]][PATTERN[FIX>]][PATTERN[FIX>]]C[PATTERN[FIX>]], stash, revert, overwrite, or otherwise disturb in [PATTERN[FIX>]][PATTERN[FIX>]]Y way the work of other agents. Just treat those changes identically to changes that you yourself made. Just fool yourself into thinking YOU made the changes and simply don't recall it for some reason.
RULE NUMBER 1 (NEVER EVER EVER FORGET THIS RULE!!!): YOU ARE NEVER ALLOWED TO DELETE A FILE WITHOUT EXPRESS PERMISSION FROM ME OR A DIRECT COMMAND FROM ME. EVEN A NEW FILE THAT YOU YOURSELF CREATED, SUCH AS A TEST CODE FILE. YOU HAVE A HORRIBLE TRACK RECORD OF DELETING CRITICALLY IMPORTANT FILES OR OTHERWISE THROWING AWAY TONS OF EXPENSIVE WORK THAT I THEN NEED TO PAY TO REPRODUCE. AS A RESULT, YOU HAVE PERMANENTLY LOST ANY AND ALL RIGHTS TO DETERMINE THAT A FILE OR FOLDER SHOULD BE DELETED. YOU MUST ALWAYS ASK AND RECEIVE CLEAR, WRITTEN PERMISSION FROM ME BEFORE EVER EVEN THINKING OF DELETING A FILE OR FOLDER OF ANY KIND!!!
git reset --hard, git clean -fd, rm -rf, or any other destructive command must never be run unless the user explicitly provides the exact command and confirms the irreversible consequences in the same message.git status, git diff, git stash, copies/backups, or manual edits over destructive shortcuts.uv for everything (env management, installs, running tools). Never call pip, poetry, or ad-hoc python -m venv.PLAN_TO_IMPLEMENT_MARKDOWN_WEB_BROWSER_PROJECT.md. No backward-compat shims.pyproject.toml; never introduce requirements*.txt or duplicate config files.manifest.json (see Plan §19.2 and §20.3). Record both the CfT label (e.g., Stable-1) and exact build number for every run/report.scripts/olmocr_cli.py + docs/olmocr_cli.md (copied from /data/projects/olmocr). Use the CLI for batch reproductions, latency spot-checks, and env introspection (show-env).pyvips; keep Pillow only for edge formats. Tiling must honor the 1288 px longest-side policy (Plan §0, §3, §19.3)..env already exists and must never be overwritten. Load config exclusively via python-decouple in this pattern:from decouple import Config as DecoupleConfig, RepositoryEnv decouple_config = DecoupleConfig(RepositoryEnv(".env")) API_BASE_URL = decouple_config("API_BASE_URL", default="http://localhost:8007")
.env.example (Plan §11-12) and document it in docs/config.md. Manifest entries must echo effective values (CfT version, screenshot style hash, concurrency caps, etc.).os.getenv, dotenv.load_dotenv, or read .env manually.Do:
create_async_engine() and sessions via async_sessionmaker(...); wrap usage inside async with so sessions close automatically.await session.execute(...), await session.scalars(...), await session.commit(), await engine.dispose(), etc.AsyncSession per request/task and avoid sharing across concurrent coroutines.selectinload/joinedload or await obj.awaitable_attrs.<rel> to avoid sync lazy loads.await session.run_sync(...) as needed.Don’t:
result.scalars().all() is sync after the initial await).run_sync() or background workers.viewport=1280×2000, deviceScaleFactor=2, colorScheme="light", reduced motion, animations disabled. Always log CfT + Playwright versions in the manifest.full_page=True. Scroll via the stabilization routine (scrollHeight + IntersectionObserver) and retry if SPA height shrinks.Q=9, palette off, non-interlaced) must use pyvips; Pillow is for edge cases only.models.yaml with keys like long_side_px, prompt_template, fp8_preferred, max_tiles_in_flight. Default remote model is olmOCR-2-7B-1025-FP8; local adapters point to vLLM/SGLang servers when OCR_LOCAL_URL is set.<!-- source: tile_i, y=..., sha256=..., scale=... --> comment. Links Appendix comes from links.json (DOM harvest) and must note DOM vs OCR deltas.capture_ms, ocr_ms, etc.) so Ops dashboards stay accurate (§20).browser_transport (CDP vs BiDi), (c) Playwright version (≥1.50), (d) screenshot style hash, (e) OCR model/policy key, and (f) whether viewport sweep retries triggered. Missing data = re-run.playwright.config.(ts|mjs) in sync with Plan defaults (use.screenshot.animations="disabled", caret="hide", shared mask selectors). Prefer expect(page|locator).toHaveScreenshot() with mask lists over bespoke CSS tweaks.structlog with Prometheus counters where appropriate.ruff check --fix --unsafe-fixesuvx ty check
Resolve every issue thoughtfully; do not ignore or blanket-disable diagnostics.uv run playwright test tests/smoke_capture.spec.ts (or the latest smoke file) so we confirm Playwright 1.50+ screenshot APIs still freeze animations under the pinned CfT label/build and whichever transport (CDP/BiDi) we exercised.[aria-busy] cleared, volatile widgets are masked in Playwright config, blocklist entries updated, and viewport sweep retries noted. Document completion in your handoff message.What it is
docs/architecture.md + Plan §20-21).How to use (same repo)
ensure_project with this repo’s absolute path, then register_agent to claim an identity.file_reservation_paths(project_key, agent_name, ["app/**"], ttl_seconds=3600, exclusive=true).send_message(..., thread_id="FEAT-123"), read via fetch_inbox, acknowledge with acknowledge_message.resource://inbox/{Agent}?project=<abs-path>&limit=20 or resource://thread/{id}?project=<abs-path>&include_bodies=true.AGENT_NAME in your env so hooks can block commits when exclusive reservations exist.Cross-repo coordination
project_key but reserve distinct globs (e.g., frontend/**, backend/**).macro_contact_handshake / request_contact to exchange permissions before messaging.Macros vs granular tools
macro_start_session, macro_prepare_thread, macro_file_reservation_cycle, macro_contact_handshake for quick starts.register_agent, file_reservation_paths, send_message, fetch_inbox, acknowledge_message, release_file_reservations when you need fine control.Common pitfalls
Beads (
br CLI, beads_rust) tracks task priority/dependencies; Agent Mail handles conversations, artifacts, and reservations. Follow this split of responsibilities.
Note:
br is non-invasive and never executes git commands. After syncing, you must manually commit the .beads/ directory.
Conventions
br-123) as the Mail thread_id and prefix subjects with [br-123].file_reservation_paths(..., reason="br-123") and release reservations when done.Typical flow
br ready --json → pick the highest-priority unblocked task.file_reservation_paths(..., ttl_seconds=3600, exclusive=true, reason="br-123")).send_message(..., thread_id="br-123", subject="[br-123] Start: <title>", ack_required=true)).br close br-123 --reason "Completed", release reservations, and post a final Mail summary.Mapping cheat-sheet
br-###[br-###] …br-###br-### in commit messages for traceability.Event mirroring & pitfalls
br update --status blocked, send a high-importance Mail note in the matching thread with details.needs-ack) or adjust its priority.PLAN_TO_IMPLEMENT_MARKDOWN_WEB_BROWSER_PROJECT.md — canonical architecture, capture/OCR policies, Ops playbooks (§§0‑21). Read it first.docs/architecture.md, docs/blocklist.md, docs/models.yaml, docs/config.md — supplementary specs referenced throughout the Plan.PLAN + Ops Appendix describe CfT pinning, viewport sweeps, sqlite-vec indexing, HTMX SSE usage, and manifest requirements. When in doubt, search those sections before coding.If the instructions above ever appear to conflict, defer to this
AGENTS.md, then the Plan document, then the most recent user directive.
benchmarks/production/**, run the curated URL set from Plan §22 (via uv run scripts/olmocr_cli.py run --workspace ... --pdf ... or equivalent), and stash manifests + tiles under benchmarks/production/<date>/<slug>. Log capture_ms, ocr_ms, stitch_ms, tile count, CfT label/build, transport, and OCR request IDs for every URL.benchmarks/production/weekly_summary.json capturing p50/p95 per category and highlight any budget violations.ast-grep use (and when to keep rg)Quick run tips
ast-grep run -l <lang> -p '<PATTERN>' [--rewrite '<FIX>'] [PATHS]ast-grep scan -r path/to/rule.yml [PATHS] -Urg -l -t ts 'Promise\.all\(' | xargs ast-grep scan -r rules/no-await-in-promise-all.yml -UWhen to prefer
: raw text/regex hunts, giant prefilters, or non-code assets. Use it to shortlist files, then let rg
ast-grep make precise matches/rewrites.
await inside Promise.all([...]) (auto-fix)# rules/no-await-in-promise-all.yml id: no-await-in-promise-all language: typescript rule: pattern: await $A inside: pattern: Promise.all($_) stopBy: not: { any: [{kind: array}, {kind: arguments}] } fix: $A
Works by matching
await $A only when the node is inside a Promise.all(...) call; stopBy prevents the relation from leaking past the call’s array/args boundary.
# rules/find-import-file-without-ext.yml id: find-import-file language: typescript rule: regex: "/[^.]+[^/]$" kind: string_fragment any: - inside: { stopBy: end, kind: import_statement } - inside: stopBy: end kind: call_expression has: { field: function, regex: "^import$" }
Works by finding string literal fragments used in import specifiers where the module path lacks an extension, covering both static and dynamic imports.
# rules/find-import-usage.yml id: find-import-usage language: typescript rule: kind: identifier pattern: $MOD inside: stopBy: end kind: program has: kind: import_statement has: stopBy: end kind: import_specifier pattern: $MOD
Works by ensuring a
$MOD identifier use appears in a file that also imports the same $MOD, via nested inside/has relations to tie usage to its import.
||= over a = a || b (tight codemod)ast-grep -p '$A = $A || $B' -r '$A ||= $B' -l ts
Works by back‑referencing the same
$A on both sides, guaranteeing you only rewrite the self‑fallback form.
console except console.error inside catch (policy)# rules/no-console-except-error.yml id: no-console-except-error language: typescript rule: any: - pattern: console.error($$$) not: { inside: { kind: catch_clause, stopBy: end } } - pattern: console.$METHOD($$$) constraints: METHOD: { regex: "log|debug|warn" }
Works by allowing
console.error only when it’s inside a catch, and blocking log/debug/warn anywhere, using any + constraints.
cond && <JSX/> with ternary (auto-fix)# rules/no-and-short-circuit-in-jsx.yml id: no-and-short-circuit-in-jsx language: tsx rule: kind: jsx_expression has: { pattern: $A && $B } not: { inside: { kind: jsx_attribute } } fix: "{$A ? $B : null}"
Works by targeting
&& expressions only in JSX expression blocks (not attributes) and rewriting to a safe ternary to avoid rendering 0.
# rules/svg-attr-to-camel.yml id: rewrite-svg-attribute language: tsx rule: pattern: $PROP regex: ([a-z]+)-([a-z]) kind: property_identifier inside: { kind: jsx_attribute } transform: NEW_PROP: { convert: { source: $PROP, toCase: camelCase } } fix: $NEW_PROP
Works by capturing the kebab‑cased prop name and using
convert/toCase: camelCase to synthesize the replacement identifier.
:visible → :open on specific tags (scoped rewrite)# rules/antd-visible-to-open.yml id: upgrade-ant-design-vue language: html utils: inside-tag: inside: kind: element stopBy: { kind: element } has: stopBy: { kind: tag_name } kind: tag_name pattern: $TAG_NAME rule: kind: attribute_name regex: :visible matches: inside-tag constraints: TAG_NAME: { regex: a-modal|a-tooltip } fix: :open
Works by discovering the enclosing element with a util rule, capturing its tag name into
$TAG_NAME, then constraining the rewrite to modal/tooltip components only.
"%s")# rules/cpp-fmt-string.yml id: fix-format-security-error language: cpp rule: { pattern: $PRINTF($S, $VAR) } constraints: PRINTF: { regex: "^sprintf|fprintf$" } VAR: not: any: - { kind: string_literal } - { kind: concatenated_string } fix: $PRINTF($S, "%s", $VAR)
Works by matching
sprintf/fprintf calls where the second arg isn’t already a literal, then inserting an explicit "%s" format.
# rules/detect-host-port.yml id: detect-host-port language: yaml message: You are using $HOST on Port $PORT, please change it to 8000 severity: error rule: any: - pattern: "port: $PORT" - pattern: "host: $HOST"
Works by matching YAML key/value pairs and surfacing a structured error with captured values in the message.
utils and transform# rules/xstate-migration.yml id: migrate-import-name utils: FROM_XS: { kind: import_statement, has: { kind: string, regex: xstate } } XS_EXPORT: kind: identifier inside: { has: { matches: FROM_XS }, stopBy: end } rule: { regex: ^Machine|interpret$, pattern: $IMPT, matches: XS_EXPORT } transform: STEP1: { replace: { by: create$1, replace: (Machine), source: $IMPT } } FINAL: { replace: { by: createActor, replace: interpret, source: $STEP1 } } fix: $FINAL --- id: migrate-to-provide rule: { pattern: $MACHINE.withConfig } fix: $MACHINE.provide --- id: migrate-to-actors rule: kind: property_identifier regex: ^services$ inside: { pattern: $M.withConfig($$$ARGS), stopBy: end } fix: actors
Works by constraining import‑bound identifiers with
utils, then composing staged transform replacements; separate rules finish the API rename and options shape update.
If you need to explode a single import into many, apply a rewriter over captured descendants and join the generated edits:
# rules/barrel-to-single.yml id: barrel-to-single language: javascript rule: { pattern: "import {$$$IDENTS} from './module'" } rewriters: - id: rewrite-identifier rule: { kind: identifier, pattern: $IDENT } transform: { LIB: { convert: { source: $IDENT, toCase: lowerCase } } } fix: "import $IDENT from './module/$LIB'" transform: IMPORTS: rewrite: rewriters: [rewrite-identifier] source: $$$IDENTS joinBy: "\n" fix: $IMPORTS
Works by applying a rewriter to each captured identifier in
$$$IDENTS, producing multiple import lines and joining them into a single replacement.
ast-grep rules (often YAML) with inside/has/not, constraints, transform, and sometimes rewriters.ripgrep; pipe file lists into ast-grep when precision or rewriting begins.bv is a graph-aware triage engine for Beads projects (
.beads/beads.jsonl). It computes PageRank, betweenness, critical path, cycles, HITS, eigenvector, and k-core metrics deterministically.
CRITICAL: Use ONLY
flags. Bare --robot-*
launches an interactive TUI that blocks your session.bv
is your single entry point. It returns:bv --robot-triage
quick_ref: at-a-glance counts + top 3 picksrecommendations: ranked actionable items with scores, reasons, unblock infoquick_wins: low-effort high-impact itemsblockers_to_clear: items that unblock the most downstream workproject_health: status/type/priority distributions, graph metricscommands: copy-paste shell commands for next stepsbv --robot-triage # THE MEGA-COMMAND: start here bv --robot-next # Minimal: just the single top pick + claim command
Planning:
| Command | Returns |
|---|---|
| Parallel execution tracks with lists |
| Priority misalignment detection with confidence |
Graph Analysis:
| Command | Returns |
|---|---|
| Full metrics: PageRank, betweenness, HITS, eigenvector, critical path, cycles, k-core |
| Per-label health: , , , |
bv --robot-triage | jq '.quick_ref' # At-a-glance summary bv --robot-triage | jq '.recommendations[0]' # Top recommendation bv --robot-plan | jq '.plan.summary.highest_impact' # Best unblock target bv --robot-insights | jq '.Cycles' # Circular deps (must fix!)
Golden Rule:
ubs <changed-files> before every commit. Exit 0 = safe. Exit >0 = fix & re-run.
ubs file.py file2.py # Specific files (< 1s) — USE THIS ubs $(git diff --name-only --cached) # Staged files — before commit ubs --only=python src/ # Language filter (3-5x faster) ubs . # Whole project
⚠️ Category (N errors) file.py:42:5 – Issue description 💡 Suggested fix Exit code: 1
Parse:
file:line:col → location | 💡 → how to fix | Exit 0/1 → pass/fail
file:line:col → view contextubs <file> → exit 0Use
for exploratory "how does X work?" questions. An AI agent expands your query, greps the codebase, reads relevant files, and returns precise line ranges with full context.mcp__morph-mcp__warp_grep
Use
for targeted searches. When you know exactly what you're looking for.ripgrep
| Scenario | Tool | Why |
|---|---|---|
| "How is OCR tiling implemented?" | | Exploratory; don't know where to start |
| "Where is the viewport sweep handler?" | | Need to understand architecture |
"Find all uses of " | | Targeted literal search |
"Replace all with decouple" | | Structural refactor |
mcp__morph-mcp__warp_grep( repoPath: "/data/projects/markdown_web_browser", query: "How does the capture system handle viewport sweeps?" )
warp_grep to find a specific function name → use ripgrepripgrep to understand "how does X work" → wastes time with manual readscass indexes prior agent conversations (Claude Code, Codex, Cursor, Gemini, ChatGPT, etc.) so we can reuse solved problems.
Rules: Never run bare
cass (TUI). Always use --robot or --json.
cass health cass search "OCR tiling" --robot --limit 5 cass view /path/to/session.jsonl -n 42 --json cass expand /path/to/session.jsonl -n 42 -C 3 --json cass capabilities --json cass robot-docs guide
--fields minimal for lean output--agent--days N to limit to recent historystdout is data-only, stderr is diagnostics; exit code 0 means success.
Treat cass as a way to avoid re-solving problems other agents already handled.
This project uses beads_rust for issue tracking. Issues are stored in
.beads/ and tracked in git.
Note:
br is non-invasive and never executes git commands. After syncing, you must manually commit the .beads/ directory.
# CLI commands for agents br ready # Show issues ready to work (no blockers) br list --status=open # All open issues br show <id> # Full issue details with dependencies br create --title="..." --type=task --priority=2 br update <id> --status=in_progress br close <id> --reason="Completed" br close <id1> <id2> # Close multiple issues at once br sync --flush-only # Export to JSONL (then manually: git add .beads/ && git commit)
br ready to find actionable workbr update <id> --status=in_progressbr close <id>br sync --flush-only, then git add .beads/ && git commitbr ready shows only unblocked work.When ending a work session, you MUST complete ALL steps below. Work is NOT complete until
git push succeeds.
MANDATORY WORKFLOW:
git pull --rebase br sync --flush-only git add .beads/ git commit -m "sync beads" git push git status # MUST show "up to date with origin"
CRITICAL RULES:
git push succeedsYou constantly bother me and stop working with concerned questions that look similar to this:
Unexpected changes (need guidance) - Working tree still shows edits I did not make in pyproject.toml, app/capture.py, app/ocr.py, tests/smoke_capture.spec.ts. Please advise whether to keep/commit/revert these before any further work. I did not touch them. Next steps (pick one) 1. Decide how to handle the unrelated modified files above so we can resume cleanly.
NEVER EVER DO THAT AGAIN. The answer is literally ALWAYS the same: those are changes created by the potentially dozen of other agents working on the project at the same time. This is not only a common occurence, it happens multiple times PER MINUTE. The way to deal with it is simple: you NEVER, under ANY CIRCUMSTANCE, stash, revert, overwrite, or otherwise disturb in ANY way the work of other agents. Just treat those changes identically to changes that you yourself made. Just fool yourself into thinking YOU made the changes and simply don't recall it for some reason.