forked from Octopus/octopus-workflow
export v0.1.8: session-scope-guard human-only three-channel ruling (#6617) + browser-debug nested OOPIF skill update
This commit is contained in:
@@ -84,6 +84,19 @@ and the provision wrapper (adds the worktree + Tier-1 runs scaffold). The
|
||||
manual 3-step is the fallback where the scripts are unavailable, same
|
||||
re-verification.
|
||||
|
||||
**Human-only tickets ([org-internal #6617]-P1).** A ticket marked
|
||||
human-only in ANY of three machine-readable forms — title `[人工执行]`
|
||||
(ASCII/【】 fullwidth variants), label `executor/human-only`, or a body
|
||||
line `executor: human` / `executor: human-only` (line-anchored,
|
||||
blockquote-tolerant) — is NOT claimable by an agent: the claim script
|
||||
refuses (exit 4, stage=precheck; takeover mode too — taking over a dead
|
||||
claim is not taking over execution rights). The title channel keeps the
|
||||
`--allow-human-only` override (explicit human instruction only, visible in
|
||||
the invoking transcript); the label/body channels have NO override — an
|
||||
explicit marker is a hard refusal for agents ([org-internal #6617] merged
|
||||
ruling). Never claim, execute, self-accept or close such a ticket on agent
|
||||
initiative.
|
||||
|
||||
**Merge-time equivalence check.** Before merging, scan the remote main
|
||||
branch's recent commits for `#<ticket>` — surfacing an equivalent
|
||||
implementation already on main *before* the merge rejection.
|
||||
|
||||
@@ -1,21 +1,33 @@
|
||||
---
|
||||
name: browser-debug
|
||||
description: >
|
||||
Use ONLY when an agent needs to interact with a live browser to debug, verify,
|
||||
or iterate on Web UI work in packages/app — navigate to the dev server, snapshot
|
||||
the DOM/accessibility tree, capture console and network errors, screenshot
|
||||
component states, and exercise user flows end-to-end. Triggers on UI bugs,
|
||||
visual regressions, layout/positioning issues, keyboard-focus problems,
|
||||
console-error reports, and any "open the page and check X" task. Loads the
|
||||
Playwright MCP toolset (browser_navigate, browser_snapshot,
|
||||
browser_take_screenshot, browser_console_messages, browser_evaluate, etc.).
|
||||
Use ONLY for interactive browser work; for writing Playwright *test files*
|
||||
use the existing e2e/ suites under packages/app, not this skill.
|
||||
Use ONLY when an agent must interact with a live browser to debug, verify,
|
||||
or iterate on Web UI work in packages/app. Triggers on UI bugs, visual
|
||||
regressions, layout/positioning issues, keyboard-focus problems,
|
||||
console-error reports, and any "open the page and check X" task. Uses the
|
||||
built-in unified browser tool surface (browser_open, browser_snapshot,
|
||||
browser_take_screenshot, browser_console_messages, browser_evaluate,
|
||||
browser_close) — contract shared/browser-tool-surface-v1 ([org-internal #4972]); the
|
||||
playwright MCP server is retired ([org-internal #4977]). Use ONLY for interactive browser
|
||||
work; for writing Playwright *test files* use the existing e2e/ suites under
|
||||
packages/app, not this skill.
|
||||
tools:
|
||||
- browser_open
|
||||
- browser_close
|
||||
- browser_snapshot
|
||||
- browser_console_messages
|
||||
- browser_take_screenshot
|
||||
- browser_evaluate
|
||||
- browser_click
|
||||
- browser_type
|
||||
- browser_act_batch
|
||||
- browser_handle_dialog
|
||||
- browser_highlight
|
||||
- browser_generate_locator
|
||||
triggers:
|
||||
- browser debug
|
||||
- open the page
|
||||
- check the page
|
||||
- screenshot the
|
||||
- inspect element
|
||||
- console error
|
||||
- visual bug
|
||||
@@ -26,8 +38,6 @@ triggers:
|
||||
- tab order
|
||||
- 浏览器调试
|
||||
- 打开页面
|
||||
- 截图
|
||||
- 视觉
|
||||
- 布局错乱
|
||||
- 对齐
|
||||
- 焦点
|
||||
@@ -36,13 +46,15 @@ role: Producer
|
||||
---
|
||||
|
||||
> Core 中立版(Increment 6a 改写,原 deferHard verbatimDir)。机制、结构与 frontmatter 保持;实例术语(工具名、路径、工单号)按 `core/adapters/TERMINOLOGY.md` 绑定到具体实例。
|
||||
|
||||
# Browser Debug
|
||||
|
||||
Interactive browser automation for Web UI work in `packages/app`. This skill
|
||||
teaches the *recipe* for driving the Playwright MCP toolset — when to reach
|
||||
for it, which tool for which job, and how to capture evidence a reviewer can
|
||||
trust.
|
||||
teaches the *recipe* for driving the unified browser tool surface — when to
|
||||
reach for it, which tool for which job, and how to capture evidence a reviewer
|
||||
can trust. The former playwright MCP server is retired ([org-internal #4977], Epic [org-internal #4972]
|
||||
N-05); the tools below are built-in and mount into the session tool face
|
||||
when this skill activates (default-off the LLM face for weight economy,
|
||||
[org-internal #5131]) — a user-configured tools_exclude vetoes the mounts.
|
||||
|
||||
## When this skill applies
|
||||
|
||||
@@ -68,37 +80,41 @@ Do **not** reach for it when:
|
||||
|
||||
## Preconditions
|
||||
|
||||
1. **Playwright MCP is configured.** The project `octopus.jsonc` carries a
|
||||
`mcp.playwright` block launching `@playwright/mcp`. If the MCP tools are
|
||||
not visible, run `/kickoff` or follow the `codegraph-setup` skill's
|
||||
recipe (the closest analog for debugging missing MCP servers).
|
||||
1. **Unified browser tools are built-in and skill-mounted.** `browser_open`,
|
||||
`browser_snapshot`, `browser_console_messages`, `browser_take_screenshot`,
|
||||
`browser_evaluate`, and `browser_close` are registered for every session
|
||||
(no MCP server needed) but default-off the LLM face — activating this skill
|
||||
mounts them onto the session tool face ([org-internal #5131]); a user tools_exclude
|
||||
vetoes the mounts
|
||||
config needed (the playwright MCP is retired, [org-internal #4977]). If the tools are
|
||||
not visible, the session runs a pre-[org-internal #4972] build — update.
|
||||
2. **Dev server is running.** The app under test must be reachable. For
|
||||
`packages/app`, run `bash script/dev-fresh.sh --full` for the dev server
|
||||
(Windows workstations: `bash script/dev-fresh-windows.sh` — dev-fresh.sh's
|
||||
stop path depends on setsid/ss, silently ineffective under Git Bash; see
|
||||
local-workstation-quirks.md §5);
|
||||
frontend is at `http://localhost:4444` and backend at `http://localhost:4096`
|
||||
(see AGENTS.md Dev services section).
|
||||
3. **Chromium is installed.** First run of `@playwright/mcp` downloads it
|
||||
automatically; if the tool reports a missing browser, run
|
||||
`packages/app`, run `bash script/dev-fresh.sh --full` for the dev server
|
||||
(Windows workstations: `bash script/dev-fresh-windows.sh` — dev-fresh.sh's
|
||||
stop path depends on setsid/ss, silently ineffective under Git Bash; see
|
||||
local-workstation-quirks.md §5);
|
||||
frontend is at `http://localhost:4444` and backend at `http://localhost:4096`
|
||||
(see AGENTS.md Dev services section).
|
||||
3. **Chromium is installed.** The headless backend drives an isolated
|
||||
Chromium; if a tool reports a missing browser, run
|
||||
`bunx playwright install chromium` once in any shell.
|
||||
|
||||
## Tool selection recipe
|
||||
|
||||
The Playwright MCP exposes many tools. Pick by *what you need to observe*,
|
||||
not by familiarity:
|
||||
The unified surface exposes focused read/navigation tools. Pick by *what you
|
||||
need to observe*, not by familiarity. Cost discipline applies: the snapshot
|
||||
answers structure/state questions, the screenshot only visual ones — take
|
||||
both in one cycle only when a visual verdict is itself the deliverable:
|
||||
|
||||
| Need | Tool | Why |
|
||||
| --- | --- | --- |
|
||||
| Open a URL | `browser_navigate` | Always the first call. |
|
||||
| Open a URL | `browser_open` | Always the first call (opens the user-visible browser pane / isolated browser). Pass `surface: "headless"` when the intent is headless — the user's pane is never touched (no confirmation bar, no pane binding) and later browser_* tools operate on the isolated headless copy; if already bound to the pane, `browser_pane_release` first. |
|
||||
| See the page structure (roles, names) | `browser_snapshot` | Returns the accessibility tree — stable across CSS refactors. Prefer this over `browser_take_screenshot` when asserting "does element X exist / is it labelled Y?". |
|
||||
| See the page *visually* | `browser_take_screenshot` | For layout, spacing, color, overflow. Attach the PNG to your report. |
|
||||
| See the page *visually* | `browser_take_screenshot` | For layout, spacing, color, overflow. Attach the PNG to your report. **Vision-model guard (#screenshot-guard):** the PNG is pixels, not text — a session model without vision CANNOT read it. If YOU cannot see images, you must delegate reading via `Task(role: "Tool")` per the `image-interpret` skill (returns a structured text spec); never attempt to interpret the PNG yourself. Pixel questions → image-interpret; DOM/state questions → `browser_evaluate`. |
|
||||
| Read console errors / warnings | `browser_console_messages` | Filter by level (`error`, `warn`). The first stop for any "page is blank" bug. |
|
||||
| Read failed network calls | `browser_network_requests` | Locate 4xx/5xx, CORS failures, hanging fetches. |
|
||||
| Click, type, hover, select | `browser_click`, `browser_type`, `browser_hover`, `browser_select_option` | Drive the flow. Always `browser_snapshot` first to get the `ref` for the target element. |
|
||||
| Assert computed style / DOM state | `browser_evaluate` | Last resort. Snapshots cover 90%; reach for `evaluate` only when you need `getComputedStyle`, scroll positions, or arbitrary JS state. |
|
||||
| Keyboard navigation | `browser_press_key` | For tab order, focus rings, escape-to-close. |
|
||||
| Record a video / trace | `browser_start_tracing`, `browser_stop_tracing` | Heavy; use only when a bug is timing-sensitive and console+snapshot can't catch it. |
|
||||
| Close the session | `browser_close` | Tear down when done; see the session cleanup section. |
|
||||
|
||||
|
||||
## Pane-first recipe (prefer over headless)
|
||||
|
||||
@@ -109,8 +125,8 @@ or exceed Playwright for the hard cases:
|
||||
| Need | Pane tool / pattern | Notes |
|
||||
| --- | --- | --- |
|
||||
| Open / bind pane | `browser_open` (default surface) | Never touch the user's pane from a headless-only intent — pass `surface: "headless"` or `browser_pane_release` first. |
|
||||
| Structure + refs | `browser_snapshot` | Open shadow is pierced; cross-origin iframes expose `f{seq}/e{n}` synthetic refs — prefer those over attr ids when acting into child frames. |
|
||||
| Act (click/type/…) | `browser_act` / `browser_act_batch` | Locators (`role=` / `text=` / …) walk open shadow. Cross-origin click/type route through CDP trusted events. |
|
||||
| Structure + refs | `browser_snapshot` | Open shadow is pierced; closed shadow is CDP-merged (`closedShadow:true`, no `e<n>`). Cross-origin iframes expose `f{seq}/e{n}` synthetic refs — prefer those over attr ids when acting into child frames. Closed hosts inside stitched OOPIF subtrees carry `closedShadow:true` (CDP merge after stitch). |
|
||||
| Act (click/type/…) | `browser_click` / `browser_type` / `browser_act_batch` | Locators (`role=` / `text=` / …) walk open shadow; after a JS miss, pane CDP pierces **closed** shadow for locate/wait/scroll (nested closed-in-open + same-origin iframe contentDocument + cross-origin OOPIF via Target.attachToTarget, including nested OOPIF-in-OOPIF host-offset chains; `DOM.focus` for type). `css=` stays light-DOM. Cross-origin click/type route through CDP trusted events. |
|
||||
| Native dialogs | `browser_handle_dialog` **before** the act | Prefer `mode: "arm"` (or `act_batch.dialog_prearm`) so the pane parks the answer before the click that opens confirm/prompt — avoids the 1.5s auto-dismiss / widget-cancel race. Bind with `messageIncludes` when the page can raise multiple dialogs. Call `mode: "disarm"` if the trigger was cancelled. |
|
||||
| Highlight / locator | `browser_highlight`, `browser_generate_locator` | Dual-leg: both pane and headless. Use highlight to confirm the ref before a write. |
|
||||
| Failure recovery | re-snapshot + path candidates | Act/locator failures may return `pathCandidates` (frame/shadow path hints). Heal scores framePath so sibling iframes do not auto-heal across frames. |
|
||||
@@ -124,28 +140,30 @@ on the pane.
|
||||
Follow these steps in order. Do not skip the snapshot step: the `ref` it
|
||||
returns is the stable handle every subsequent tool needs.
|
||||
|
||||
1. `browser_navigate` to the page where the bug lives.
|
||||
1. `browser_open` the page where the bug lives.
|
||||
2. `browser_console_messages` — record any errors *before* touching anything.
|
||||
Many "interaction bugs" are actually load-time errors.
|
||||
3. `browser_snapshot` — locate the target element; capture its `ref` and
|
||||
accessible name.
|
||||
4. Drive the interaction with `browser_click` / `browser_type` /
|
||||
`browser_press_key` until the bug reproduces.
|
||||
5. Re-read `browser_console_messages` and `browser_network_requests` —
|
||||
capture the *delta* introduced by the interaction.
|
||||
3. `browser_snapshot` — locate the target element; capture its accessible
|
||||
name.
|
||||
4. If the reproduction needs interaction beyond reading, use
|
||||
`browser_evaluate` sparingly to probe state — the unified surface is
|
||||
read-focused; drive deep flows via the e2e suites when needed.
|
||||
5. Re-read `browser_console_messages` — capture the *delta* introduced by
|
||||
the interaction / page state.
|
||||
6. `browser_take_screenshot` (or a second `browser_snapshot`) to freeze the
|
||||
broken state.
|
||||
7. Report: URL, the minimal interaction sequence, console delta, network
|
||||
delta, screenshot, and the suspected component path in
|
||||
`packages/app/src/...`.
|
||||
7. Report: URL, the observation sequence, console delta, screenshot, and the
|
||||
suspected component path in `packages/app/src/...`.
|
||||
|
||||
## Standard recipe — verify a UI fix
|
||||
|
||||
1. `browser_navigate` to the affected page.
|
||||
1. `browser_open` the affected page.
|
||||
2. `browser_snapshot` — confirm the fixed element is present with the
|
||||
expected accessible name.
|
||||
3. `browser_take_screenshot` — full page **and** element-cropped if the fix
|
||||
is local.
|
||||
3. `browser_take_screenshot` — only when the fix is visual (layout, styling,
|
||||
rendering); full page **and** element-cropped if the fix is local. For
|
||||
non-visual fixes (logic, state, wiring) the snapshot plus console delta is
|
||||
the evidence — skip the screenshot.
|
||||
4. If the fix touched layout, `browser_evaluate` a `getBoundingClientRect()`
|
||||
or `getComputedStyle()` on the key node and paste the value into your
|
||||
report. Numbers beat adjectives.
|
||||
@@ -169,7 +187,7 @@ When a `verify` work item has an E2E or UI DoD entry:
|
||||
reference (UI-touching PRs, `verify` skill Phase 2.7 / contract
|
||||
`browser-evidence-4486/shared/evidence-ref-v1`), promote the captures
|
||||
into an evidence pack first — feed COPIES through
|
||||
`writeEvidencePack` (`<harness-package>/src/browser/evidence-pack.ts`,
|
||||
`writeEvidencePack` (`packages/octopus/src/browser/evidence-pack.ts`,
|
||||
the single mandatory sanitize boundary; the `.playwright-mcp/` layer
|
||||
keeps its current semantics, additive not replaced) and cite the pack
|
||||
directory. Evidence ladder: raw capture → `.playwright-mcp/` working
|
||||
@@ -182,9 +200,9 @@ When a `verify` work item has an E2E or UI DoD entry:
|
||||
| --- | --- |
|
||||
| "The unit test already covers it." | Unit tests assert component logic, not what Chromium actually renders. Visual and focus bugs live in the gap. |
|
||||
| "I can tell from the JSX that it's aligned." | Computed layout depends on parent containers, fonts, and viewport. Screenshot the real page. |
|
||||
| "Browser automation is overkill for a small change." | A `browser_navigate` + `browser_take_screenshot` pair is ~2 seconds. The cost is in *not* looking. |
|
||||
| "Browser automation is overkill for a small change." | A `browser_open` + `browser_snapshot` read is ~2 seconds — cheap. The cost is in *not* looking; add the screenshot only where the question is visual. |
|
||||
| "I'll just run the whole e2e suite." | The suite answers "did anything break?" — it does not answer "does this specific change look right?". |
|
||||
| "Snapshot is enough, skip the screenshot." | Accessibility trees hide overflow, clipping, and z-index bugs. Take both for visual changes. |
|
||||
| "Snapshot is enough, skip the screenshot." | Depends on the claim. For a visual change it is backwards — accessibility trees hide overflow, clipping, and z-index bugs, so take the screenshot too. For a non-visual claim (presence, label, state) the snapshot alone IS the observation; don't pad it with pixels. |
|
||||
|
||||
## Boundaries
|
||||
|
||||
@@ -203,18 +221,12 @@ When a `verify` work item has an E2E or UI DoD entry:
|
||||
|
||||
## Session cleanup (mandatory)
|
||||
|
||||
A Playwright MCP browser is a real Chrome with a `/tmp` user-data-dir — its
|
||||
mode follows `mcp.playwright.headless` (`headless-field-v1`, [org-internal #4393]): the repo
|
||||
default `auto` spawns headed on desktop (win32/darwin; linux only with
|
||||
DISPLAY/WAYLAND_DISPLAY set) and headless otherwise; an explicit `true`/`false`
|
||||
or `OCTOPUS_MCP_HEADLESS=1|0` pins it. The mode is fixed per new session —
|
||||
switching the config does not hot-switch a running browser. It
|
||||
stays alive as long as its MCP server runs, and the MCP server stays alive as
|
||||
long as its parent octopus backend runs. When a browser-debug session ends
|
||||
without an explicit `browser_close`, OR the octopus session times out mid-task,
|
||||
the Chrome + its MCP server are orphaned and accumulate across sessions —
|
||||
burning CPU and leaving dead profile dirs (issue [org-internal #1315]); in headed mode the
|
||||
orphan is a visible stray window.
|
||||
The unified surface's isolated backend is a real Chrome with a `/tmp`
|
||||
user-data-dir. It stays alive as long as its parent octopus backend runs.
|
||||
When a browser-debug session ends without an explicit `browser_close`, OR the
|
||||
octopus session times out mid-task, the Chrome is orphaned and accumulates
|
||||
across sessions — burning CPU and leaving dead profile dirs (issue [org-internal #1315]); in
|
||||
headed mode the orphan is a visible stray window.
|
||||
|
||||
**Iron rule: every browser-debug session MUST close its browser before ending.**
|
||||
|
||||
@@ -236,19 +248,16 @@ orphan is a visible stray window.
|
||||
|
||||
**Why this matters:** a single forgotten `browser_close` leaves a Chrome
|
||||
subtree (8+ processes) running indefinitely. Over days this is hundreds of
|
||||
orphaned processes and wasted CPU. The MCP server does not auto-close its
|
||||
browser on disconnect — only an explicit `browser_close` (or process reaping)
|
||||
releases it.
|
||||
orphaned processes and wasted CPU. Only an explicit `browser_close` (or
|
||||
process reaping) releases it.
|
||||
|
||||
## Screenshot output paths
|
||||
|
||||
The Playwright MCP server is launched WITHOUT `--output-dir` (see
|
||||
`octopus.jsonc` → `mcp.playwright.command`): its default output location is
|
||||
`.playwright-mcp/` in the process cwd (the worktree root), gitignored and
|
||||
auto-evicted at 100 MB via `--output-max-size`. Auto-named output (no
|
||||
`filename`) lands there — but an explicit `filename` can resolve against the
|
||||
cwd and drop the PNG into the repo root, where the `/*.png` gitignore
|
||||
backstop hides it from `git status` and nothing ever cleans it up.
|
||||
Screenshots from `browser_take_screenshot` land in `.playwright-mcp/` in the
|
||||
process cwd (the worktree root), gitignored. An explicit `filename` can
|
||||
resolve against the cwd and drop the PNG into the repo root, where the
|
||||
`/*.png` gitignore backstop hides it from `git status` and nothing ever
|
||||
cleans it up.
|
||||
|
||||
**Iron rule: 截图文件名必须写进 `.playwright-mcp/`。** Every `filename`
|
||||
passed to `browser_take_screenshot` (or any tool that writes a file) MUST
|
||||
@@ -281,10 +290,10 @@ Two valid destinations for screenshots, by purpose:
|
||||
octopus UI. The endpoint exists but has returned 500 on this instance;
|
||||
verify before relying on it.
|
||||
3. **Publish to the wiki evidence namespace `{slug}/verify/evidence/{name}`
|
||||
via `wiki 读写 API(见 TERMINOLOGY)`** — last resort only, when no other channel
|
||||
via git direct-push to `octopus.wiki.git` (`_shared/gitea-write-patterns.md` top-of-file, [org-internal #6180])** — last resort only, when no other channel
|
||||
works AND the evidence must outlive the worktree (this is the same durable
|
||||
channel `verify` mandates for DoD evidence entries — see
|
||||
`core/skills/verify/SKILL.md` References). Keep it small:
|
||||
`.octopus/skills/verify/SKILL.md` References). Keep it small:
|
||||
≤5 images per PR, each ≤200KB (compress/downscale, prefer element
|
||||
crops over full-page).
|
||||
|
||||
@@ -302,13 +311,19 @@ prefix is the real fix; rely on that, not on the backstop.
|
||||
|
||||
## References
|
||||
|
||||
- `core/skills/frontend/SKILL.md` — where UI changes are planned; invoke
|
||||
- `.octopus/skills/image-interpret/SKILL.md` — REQUIRED when the session model
|
||||
has no vision: `browser_take_screenshot` writes a PNG the driving model
|
||||
cannot read. Delegate reading via `Task(role: "Tool")` (structured text spec
|
||||
back); never self-interpret pixel content. Pixel questions (layout, color,
|
||||
spacing) → image-interpret; DOM/state questions (form values, validation) →
|
||||
`browser_evaluate`.
|
||||
- `.octopus/skills/frontend/SKILL.md` — where UI changes are planned; invoke
|
||||
this skill during Phase 3 / Phase 4 to verify each state visually.
|
||||
- `core/skills/implement/SKILL.md` — Frontend Mode; pair with
|
||||
- `.octopus/skills/implement/SKILL.md` — Frontend Mode; pair with
|
||||
`browser-debug` when the work item touches rendering.
|
||||
- `core/skills/implement/SKILL.md` (Mode: bugfix) — Phase 1 reproduction; use this skill
|
||||
- `.octopus/skills/implement/SKILL.md` (Mode: bugfix) — Phase 1 reproduction; use this skill
|
||||
to capture the failing state before isolating root cause.
|
||||
- `core/skills/verify/SKILL.md` — Phase 2 / DoD matrix; use this skill
|
||||
- `.octopus/skills/verify/SKILL.md` — Phase 2 / DoD matrix; use this skill
|
||||
to generate screenshot evidence for UI-tagged DoD entries.
|
||||
- `packages/app/e2e/` — permanent Playwright test suites; this skill is the
|
||||
ad-hoc complement, not a replacement.
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "octopus-workflow",
|
||||
"version": "0.1.7",
|
||||
"version": "0.1.8",
|
||||
"description": "Standalone workflow core: provider-neutral agent workflow corpus (skills / rules / checklists / templates / schemas) with drift guards, extracted from the octopus agent platform.",
|
||||
"license": "MIT",
|
||||
"private": false,
|
||||
@@ -16,4 +16,4 @@
|
||||
"type": "git",
|
||||
"url": "https://eightarms.net/Octopus/octopus-workflow"
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user