一键导入
hgraf-review-pr
Harmonograf-specific PR review checklist — cross-layer coherence, state machine safety, test coverage, UI regression screens.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Harmonograf-specific PR review checklist — cross-layer coherence, state machine safety, test coverage, UI regression screens.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
| name | hgraf-review-pr |
| description | Harmonograf-specific PR review checklist — cross-layer coherence, state machine safety, test coverage, UI regression screens. |
You've been asked to review a PR on the harmonograf repo, or you're self-reviewing before pushing. Generic PR-review advice applies, but harmonograf has cross-cutting concerns (proto → client → server → frontend) that are easy to miss if you only look at one layer.
AGENTS.md at the repo root — the project vision, the
three-component architecture.hgraf-add-proto-field, hgraf-add-drift-kind,
hgraf-migrate-sqlite-schema, etc.). This review skill is the
meta layer — it asks whether the right sub-skill was followed.Do these in order. Don't jump around.
Harmonograf is a shared-schema system. When the data model changes, the change must land in all layers atomically. For each of the following, check both sides are consistent:
| Change type | Layers that must move together |
|---|---|
| Add/rename proto field | proto/ + Python stubs (client + server) + TS stubs (frontend) + converters on both sides + persistence |
| New SpanKind / ControlKind / Capability / AnnotationKind | Proto enum + client emission + server routing + frontend rendering (convert.ts + colors.ts / hooks.ts) |
| New drift kind | DriftReason enum + detector path + throttle table + refine prompt awareness + tests |
| SQLite schema | SCHEMA dict + PRAGMA-guarded ALTER + all INSERT/SELECT statements (positional!) |
| Reporting tool | _TOOL_DEFINITIONS + before_tool_callback dispatcher + state_protocol keys + docs/reporting-tools.md |
If any column in the matching row is missing, that's a cross-layer coherence bug. File a comment.
The client's _AdkState is monotonic. Check:
task.status directly? If so, it must go through _set_task_status (which enforces _ALLOWED_TRANSITIONS). Direct assignment is a bug unless inside _apply_refined_plan's terminal-preservation loop._apply_refined_plan? Refines must go through that method — it preserves terminal statuses, bumps revision_index, canonicalizes assignees.revision_index by hand? Never — always through _apply_refined_plan.adk.py:3283? Critical-severity drifts legitimately bypass; anything else should not.Cross-reference with hgraf-interpret-invariant-violations.md for the 8-rule taxonomy.
before_model_callback, after_model_callback, before_tool_callback, on_event_callback)? These run on the hot path — blocking operations break the agent's perceived latency. Move to background._run_invariants add O(n²) work on a hot path? Invariants run after every walker turn; be budget-aware.Cross-reference hgraf-profile-callback-perf.md.
For each behavior change, look for:
Red flags:
time.sleep rather than deterministic monotonic-time injection.InvariantChecker silently relying on module-level state (see pitfall in hgraf-interpret-invariant-violations.md).For UI changes:
AGENTS.md mandates this.) Ask explicitly — "did you verify in a browser?"uiStore, SessionStore, TaskRegistry)? If yes, every consumer needs a sanity check.index.css? Grep for var(--<name>) across the frontend — if the variable is referenced from a component not touched by the PR, that component's visual state is affected.*_pb2.py, *_pb2.pyi, *_pb.ts — generated files. If the proto changed, all of these should have been regenerated in the same PR. If only one language regenerated, comment.pnpm-lock.yaml, uv.lock — lockfiles. Changes are fine; unexpected changes (e.g., a PR that shouldn't touch deps but does) warrant a comment.frontend/dist/ — should never be committed. If it is, reject.docs/ gain an entry? docs/reporting-tools.md is the canonical reference for those.AGENTS.md at the root need an update to reflect the change? (Rare — only for architecture-level edits.).agents/ — is there a skill that now needs updating because the PR changed its prerequisites (e.g., moved a file, renamed a symbol)?adk.py:378 _DRIFT_REFINE_THROTTLE_SECONDS = 2.0. A new test that fires drifts in quick succession will see only the first one trigger a refine. New tests need deterministic monotonic-time injection or they flake.
adk.py:3494-3520 preserves RUNNING/COMPLETED/FAILED/CANCELLED across refines. A change that "simplifies" this loop is a Gantt history regression — reject unless the author proves the preservation is being done elsewhere.
InvariantChecker.check returns violations in stable order (invariants.py:93-118). Tests that filter violations[0] rely on that order. A refactor that reorders the check list will break those tests silently (they'll filter the wrong violation).
hgraf-migrate-sqlite-schema.md pitfall. If a PR adds a column and all INSERTs in the codebase use positional placeholders, the new column must be the LAST one, or every INSERT must update. Grep for INSERT INTO <table> across the server code.
types.proto:387-390 — control acks must ride upstream on StreamTelemetry. A PR that routes control responses through a separate channel violates the contract; the server won't correlate them with the originating request.
Spans are telemetry only; they do not drive task state. A PR that inspects span fields to infer task status is reintroducing the pre-refactor architecture. Reject.
nit:. Don't block on these.One principle: the PR description is the first thing you read, the code is the second. If the description says "fixes X" but the code does Y, ask before reviewing the code — you might be reviewing with the wrong model in your head.
# Run whichever tests overlap with the diff
git diff --stat main | awk '{print $1}' | grep -E '\.(py|ts)' | head
uv run pytest client/tests -x -q
uv run pytest server/tests -x -q
cd frontend && pnpm test && pnpm typecheck && pnpm lint
.agents/ skills and the project memory at ~/.claude/projects/.../memory/ may carry invariants that aren't in the PR diff. If the change contradicts a saved rule, ask the author about it.Understand and safely change heartbeat interval, stuck threshold, and timeout constants — client cadence, server detection math, frontend signal.
Add a new AnnotationKind — proto, storage, ingress RPC, optional downstream delivery to agents, frontend authoring UI, tests.
Add a new agent Capability — proto enum, client advertisement, server ingest, frontend gating in the control UI.
Add a new ControlKind — capability advertisement, client handler, server routing, ack semantics, frontend button, and tests — all the way through.
Add a new drift kind end-to-end. Goldfive owns the detector + enum; harmonograf reflects the kind through the intervention aggregator and the UI timeline.
Script a complex multi-turn FakeLlm scenario — function calls, tool chains, drift events, side-effect hooks, partial responses — for deterministic adk test coverage.